What are the semantic consequences: volatile-mutable versus: unsynchronized-mutable?

I studied lib clojure when I noticed that the mutable field was annotated with ^: unsynchronized-mutable . Mutable is changed, but I had no idea what the unsynchronized part meant, so I read the docs that contain:

Note that mutable fields are extremely difficult to use correctly, and are only present to help create higher clojure types as constructors in Clojure. They are intended only for experts - if the semantics and consequences of: volatile-mutable or: unsynchronized-mutable are not immediate, you should not use them.

I couldnโ€™t get a nuance: does this mean that in practice it doesnโ€™t matter which annotation of variability I choose, or that people should just forget about using mutable types in general?

And, for the sake of curiosity, at a lower level of abstraction, what is the semantic difference between them?

Thanks!

+5
source share
3 answers

Well, this does not say that people should forget about using mutable types. He says that anyone using them should know the difference between unsynchronized and volatile (and implying that this is not a Clojure problem, as otherwise it will be explained in docstring). I don't know a single final explanation, but you need to understand the java memory model, as well as the streaming and synchronization in general, before using Clojure deftype mutable fields.

I do not have a final link, but Wikipedia seems to have a useful article on this topic (nb I found it just now, and just took it off).

+2
source

These are java constructs, so you will not see them anywhere in the clojure documentation other than "do not use this."

Reads and writes are atomic for all variables declared "volatile".

Unsynchronized fields are ordinary Java variable variables.

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

In practical terms, this means that if you have a data structure, when multiple threads access data to read or write volatile targets will always be consistent; that is, you will always receive a data object that is either completely or completely after the operation on this data.

Sorry if this does not mean 100%; semantics are complex; read about it if you want a deeper understanding: When do you use the volatile keyword in Java?

TL; DR;

Volatiles are slightly less effective than unsynchronized; but it gives better data transfer guarantees.

Avoid both of them if you can, but if you need to use them, you probably want to :volatile-mutable

+2
source

It is said that if you do not understand the difference between :volatile-mutable and :unsynchronized-mutable , you should use Clojure reference types, and not directly using mutable fields.

These two types of variability have different strategies for ensuring thread consistency for common volatile data, and this leads to different read / write performance. Sometimes you can get better performance by tweaking to use a particular kind of variability. You may get strange and hard to understand errors if you use them naively.

+1
source

Source: https://habr.com/ru/post/987971/


All Articles