Correct understanding of concepts like volatile, syncronized and AtomicReference?

1k views Asked by At

I would like to be sure I understood correctly these concepts. The explanations/confirmations will help me a lot and I'm sure many other programmers. So here are my understandings of these concepts, resulted from my investigation:

  1. Volatile is used when you want to share a variable between multiple threads. a) What is the difference bwteen declaring a (shared between threads) variable volatile and not to ? b) Should we always declare it volatile in we're accessing it from different threads? c) Does it make sense to synchronize a volatile variable?

  2. AtomicReference is a class that wraps our object and provides some atomic operations on it ( compareAndSet, lazySet and weakCompareAndSet ). This is all, no synchronization, no nothing. a) Does it make sense to declare an AtomicReference volatile? b) But synchronize it?, since AtomicReference.get is not synchronized nor the set?

  3. Synchronization is a concept that means sequential access to a variable that is shared between multiple threads. It can be done by instance and by class. Synchronization can be added into methods headers or in code blocks. No mistery here I hope :)

Regards, Aurelian

2

There are 2 answers

4
Marko Topolnik On BEST ANSWER

a) What is the difference bwteen declaring a (shared between threads) variable volatile and not to?

If it isn't volatile, a write to it by one thread may never be seen by any other threads.

b) Should we always declare it volatile in we're accessing it from different threads?

Unless it is always accessed from a synchronized block.

c) Does it make sense to synchronize a volatile variable?

It does, but only if the volatile variable is also accessed outside of any synchronized block.

a) Does it make sense to declare an AtomicReference volatile?

It definitely does, if you plan to change the instance at runtime. Usually, however, it is better to have a final AtomicReference.

b) But synchronize it?, since AtomicReference.get is not synchronized nor the set?

Synchronizing AtomicReference access defeats its very purpose of lock-free multithreading. Choose either synchronization or AtomicReference.

1
scottb On

Volatile is used when you want to share a variable between multiple threads. a) What is the difference bwteen declaring a (shared between threads) variable volatile and not to ? b) Should we always declare it volatile in we're accessing it from different threads? c) Does it make sense to synchronize a volatile variable?

To understand volatile, it is useful to think about the architectures of modern computer system hardware.

In order to accelerate performance, EACH PROCESSOR OR CORE has it's own local memory cache. Data that is present in this cache is local to the particular processor and is not visible to other processors. In addition, there can be data caches at almost any level up to and including the JVM itself.

When you think of threads in this way, i.e. a unit of execution that can be divided up among processors, it is easy to understand a very important fact of the Java Memory Model:

There is no guarantee that changes to a shared variable made in one thread will become visible to other threads that access the same variable (without synchronization).

Again, imagine that the data that has updated the shared variable is still located in a local processor cache that is not available to the other cores (and, so, therefore not available to the other threads executing on them).

The volatile keyword provides you with a way of guaranteeing that changes to shared variables get written out to memory right away so that the changes that occur to them are visible to other threads. Volatile is useful in simple situations, and while it provides improved liveness to data, it provides no guarantees of atomicity and so it can provide no guarantees that race conditions on the shared variable still won't occur.

If mutating an object from one logical state to another requires multiple steps, then synchronizing the access to the object's state becomes necessary to preserve atomicity (either the update happens completely or not at all) even if the state transition involves only variables declared volatile.