1

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

aureliangtx
  • 317
  • 6
  • 18
  • Possible duplicate of : http://stackoverflow.com/questions/9749746/what-is-the-difference-of-atomic-volatile-synchronize?rq=1 – dantuch Aug 25 '13 at 11:44

2 Answers2

2

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • But since get and set from AtomicReference are not syncronized, couldn't we mess up things if the access them from multiple threads? It looks to me AtomicReference's only job is those 3 methods (compareAndSet, lazySet and weakCompareAndSet ) to be atomically executed and nothing more. Am I wrong? – aureliangtx Aug 25 '13 at 14:12
  • I am saying this because the Unsafe class is only used in those 3 methods, and I don't see any synchronized blocks anywhere,thanks – aureliangtx Aug 25 '13 at 14:30
  • Yes, those operations are atomic both from the perspective of the calling thread, as well as from any other thread. They constitute the basic elements of lock-free multithreading. If the fine granularity of those operations is not enough for a certain use case, then AtomicReference is not suited for it and should not be used at all. – Marko Topolnik Aug 25 '13 at 16:28
  • Underneath, AtomicReference uses a volatile member, ensuring that the get() and set() and similar operations are accessing non-thread-specific memory. This is how it attains thread safety without synchronization. As Marko and ScottB both stated, there are really only two ways to guarantee that a particular thread is seeing the "real" (non-thread-specific) value of a particular variable: that variable is declared as "volatile" which means it should not be cached in thread-specific memory, or that variable is guarded by a synchronized block (all thread-specific memory is updated at synchronize). – Tom Dibble Dec 09 '15 at 16:51
2

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.

scottb
  • 9,908
  • 3
  • 40
  • 56
  • Volatile does not itself provide an atomicity guarantee, but setting a reference does guarantee atomicity so if all that needs to be kept up to date and consistent is a single reference then volatile is adequate (AtomicReference.get() and .set() just operate on a volatile field reference). So, if you are worried about a specific shared variable then volatile is fine, but if you have two variables or more needing to be kept in sync, or are updating values in a 'volatile' object, then you will need synchronization or other locking. – Tom Dibble Dec 09 '15 at 16:58