Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the semantic implications of :volatile-mutable versus :unsynchronized-mutable?

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

Note well that mutable fields are extremely difficult to use correctly, and are present only to facilitate the building of higher level constructs, such as Clojure's reference types, in Clojure itself. They are for experts only - if the semantics and implications of :volatile-mutable or :unsynchronized-mutable are not immediately apparent to you, you should not be using them.

I couldn't get the nuance: is it saying that in practice it doesn't matter which mutability annotation I choose, or that people should just forget about using mutable types altogether?

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

Thanks!

like image 547
konr Avatar asked Jan 15 '14 01:01

konr


2 Answers

These are java constructs, which is why you'll not see them referenced anywhere in the clojure documentation except 'don't use this'.

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

Unsynchronized fields are regular Java mutable fields.

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

Practically speaking, it means that if you have a data structure, when multiple threads access the data for read or write volatile targets will always be consistent; that is, you will always get a data object that is from either completely before, or completely after an operation on that data.

I'm sorry if that doesn't make 100% sense; the semantics are complex; have a read of this if you want a deeper understanding: When exactly do you use the volatile keyword in Java?

tldr;

Volatile is slightly less performant than unsynchronized; but it gives better cross thread data guarantees.

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

like image 142
Doug Avatar answered Oct 16 '22 16:10

Doug


Well, it's not saying that "people" should forget about using mutable types. It's saying that any person using them should know the difference between unsynchronized and volatile (and implying that this is not a Clojure-specific issue, since otherwise it would be explained in the docstring). I don't know offhand of a single definitive explanation, but you should understand the java memory model, and about threading and synchronization in general, before using Clojure's mutable deftype fields.

I don't have a definitive reference at hand, but Wikipedia seems like it has a useful article on the topic (nb I found it just now, and have only skimmed it).

like image 3
amalloy Avatar answered Oct 16 '22 16:10

amalloy