我正在尝试从网站上提供的 API 和文档中学习 Clojure。我对 Clojure 中的可变存储有点不清楚,我想确保我的理解是正确的。如果有任何想法我错了,请告诉我。
编辑:当我收到关于其正确性的评论时,我正在更新它。
免责声明:所有这些信息都是非正式的并且可能是错误的。不要使用这篇文章来了解 Clojure 的工作原理。
变量 总是包含一个根绑定(bind),可能还有一个每个线程的绑定(bind)。它们与命令式语言中的常规变量相当,不适合在线程之间共享信息。 (感谢亚瑟乌尔费尔特)
引用 是支持原子事务的线程之间共享的位置,这些原子事务可以更改单个事务中任意数量的引用的状态。在退出同步表达式(dosync)时提交事务,并使用 STM 魔法(回滚、队列、等待等)自动解决冲突
代理商是通过调度独立的 Action 函数来改变代理的状态,使信息能够以最小的开销在线程之间异步共享的位置。代理会立即返回,因此是非阻塞的,尽管在分派(dispatch)函数完成之前不会设置代理的值。
原子是可以在线程之间同步共享的位置。它们支持不同线程之间的安全操作。
这是我基于何时使用这些结构的友好总结:
另外,一个相关的概念是函数
future
。 .对我来说,future 对象似乎可以被描述为一个同步代理,其中在计算完成之前根本无法访问该值。它也可以被描述为一个非阻塞的 Atom。这些是对 future 的准确概念吗?
请您参考如下方法:
听起来你真的在使用 Clojure!做得好 :)
Vars 在所有线程中都有一个可见的“根绑定(bind)”,每个单独的线程都可以更改它看到的值,而不会影响其他线程。如果我的理解是正确的,那么一个 var 不能只存在于一个线程中而没有一个对所有人可见的根绑定(bind),并且在第一次使用 (def ... ) 定义它之前它不能“反弹”。
Refs 在包含更改的 (dosync ... ) 事务结束时提交,但仅在事务能够以一致状态完成时提交。