2014-01-15 24 views
5

我正在研究clojure库,当我注意到一个可变字段被注释为^:unsynchronized-mutable。易变是可变的,但我不知道是什么不同步部分的意思,所以我读了docs,其中包含:什么是语义含义:volatile-mutable与:unynchronized-mutable?

说明清楚,易变的领域是非常困难的正确使用 ,并且只存在于便于在Clojure 本身中构建更高级别的构造,如Clojure的参考类型。它们仅供专家使用 - 如果volatile-mutable或:unsynchronized-mutable的语义和影响 不是立即显示给您的 ,则不应使用它们。

我无法得到细微差别:它是否说在实践中,我选择哪个可变性注释或人们应该忘记使用可变类型?

而且,为了好奇,在较低的抽象层次上,它们之间的语义差异是什么?

谢谢!

+3

这肯定是说你应该不** **使用可变领域。 – Chuck

+0

现在,源代码示例的链接已被破坏,但对于任何人现在想知道警告的来源,它在['deftype'](http://clojuredocs.org/clojure.core/deftype)的文档字符串中。 – Mars

回答

2

嗯,这并不是说“人”应该忘记使用可变类型。这就是说,任何使用它们的人都应该知道非同步和不稳定的区别(并且暗示这不是Clojure特有的问题,否则会在文档字符串中解释)。我不知道一个明确的解释,但在使用Clojure的可变deftype字段之前,您应该了解Java内存模型,以及一般的线程和同步。

我没有明确的参考资料,但维基百科似乎有关于该主题的useful article(我刚发现它,并且只是剔除它)。

+0

我认为这比“任何使用它们的人都应该知道区别”都要进一步。它的确这么说,但它也表示它们只存在于构建更高层次的构造中,在大多数情况下,这对我来说是一种非常强烈的挫折,即使是那些了解这两种类型的影响的人也是如此。 – Chuck

1

这是说,如果你不明白:volatile-mutable:unsynchronized-mutable之间的区别,你应该使用Clojure的引用类型,而不是直接使用可变字段。

这两种可变性具有不同的策略来保证共享可变数据的线程之间的一致性,并且这导致读/写操作的不同性能。有时你可以通过微调使用某种特定的可变性来获得更好的性能。如果你天真地使用它们,你会变得奇怪而难以理解。

2

这些是java结构,这就是为什么你不会在clojure文档中的任何地方看到它们,除非'不要使用这个'。

对于声明为'volatile'的所有变量,读取和写入是原子的。

未同步的字段是常规的Java可变字段。

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

实事求是地讲,这意味着,如果你有一个数据结构,当多个线程访问数据进行读取或写入挥发性目标将始终是一致的;也就是说,您将始终从完全在数据操作之前或完全在该数据操作之后获取数据对象。

对不起,如果这不能100%的感觉;语义复杂;如果您想深入了解,请阅读以下内容:When exactly do you use the volatile keyword in Java?

tldr;

挥发性略低于未同步;但它提供了更好的跨线程数据保证。

避免他们两个,如果你可以,但如果你需要使用一个,你可能想:volatile-mutable