Difference between synchronization of field reads and volatile - java

In a nice article with some concurrency tips, an example was optimized to the following lines:
double getBalance() {
Account acct = verify(name, password);
synchronized(acct) { return acct.balance; }
}
If I understand that correctly, the point of the synchronization is to ensure that the value of acct.balance that are read by this thread is current and that any pending writes to the fields of the object in acct.balance are also written to main memory.
The example made me think a little: wouldn't it be more efficient to just declare acct.balance (i.e. the field balance of class Account) as volatile? It should be more efficient, save you all the synchronize on accesses to acct.balance and would not lock the whole acct object. Am I missing something?

You are correct. volatile provides a visibility guarantee. synchronized provides both a visibility guarantee AND serialisation of protected code sections. For VERY simple situations volatile is enough, however it is easy to get into trouble using volatile instead of synchronisation.
If you were to assume that Account has a way of adjusting its balance then volatile is not good enough
public void add(double amount)
{
balance = balance + amount;
}
Then we have a problem if balance is volatile with no other synchronization. If two threads were to try and call add() together you could have a "missed" update where the following happens
Thread1 - Calls add(100)
Thread2 - Calls add(200)
Thread1 - Read balance (0)
Thread2 - Read balance (0)
Thread1 - Compute new balance (0+100=100)
Thread2 - Compute new balance (0+200=200)
Thread1 - Write balance = 100
Thread2 - Write balance = 200 (WRONG!)
Obviously this is wrong because both threads read the current value and updated independently and then wrote it back (read, compute, write). volatile does not help here so you would need synchronized to ensure one thread completed the entire update before the other thread began.
I general find that if when writing some code I think "can I use volatile instead of synchronized" the answer might well be "yes" but the time/effort of figuring it out for sure and the danger of getting it wrong is not worth the benefit (minor performance).
As an aside a well written Account class would handle all the synch logic internally so callers don't have to worry about it.

Declaring Account as volatile is subjected to following issues and restrictions
1."Since other threads cannot see local variables, declaring local variables volatile is futile." Moreover If you try to declare a volatile variable in a method, you'll get a compiler error in some cases.
double getBalance() {
volatile Account acct = verify(name, password); //Incorrect ..
}
Declaring Account as volatile warns the compiler to fetch them fresh each time, rather than caching them in registers. This also inhibits certain optimizations that assume no other thread will change the values unexpectedly.
If you need synchronized to co-ordinate changes to variables from different threads,
volatile does not guarantee you atomic access,because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation. Unless you are sure that acct = verify(name, password); is single atomic operation, you cannot guarantee excepted results
If variable acct is an object reference, then chances are it may be null .Attempting to synchronize on a null object will throw a NullPointerException using synchronized.
(because you're effectively synchronizing on the reference, not the actual object)
Where as volatile does not complain
Instead you could declare a boolean variable as volatile like here
private volatile boolean someAccountflag;
public void getBalance() {
Account acct;
while (!someAccountflag) {
acct = verify(name, password);
}
}
Note you cannot declare someAccountflag as synchronized, as
you can't synchronize on a primitive with synchronized, synchronized only works with object variables, where as primitive or object variable may be declared volatile
6.Class final static fields doesn't need to be volatile, JVM takes care of this problem. So the someAccountflag need not be even declared volatile if it is a final static
or you could use lazy singleton initialization making Account as a singleton object
and declare it as follows:
private final static AccountSingleton acc_singleton = new AccountSingleton ();

If multiple threads are modifying and accessing the data, synchronized guarantees data consistency among multiple threads .
if single thread is modifying the data and multiple threads try to read the latest value of data, use volatile construct.
But for above code, volatile does not guaranty memory consistency if multiple threds modify balance. AtomicReference with Double type serves your purpose.
Related SE question:
Difference between volatile and synchronized in Java

Related

How does the JMM deal with a section of code where both the effects of synchronization and volatility occur (and cover for each other)? [duplicate]

With following class,
// This class should be thread-safe!!!
class BankAccount {
private long balance; // Should it be volatile?
synchronized void deposit(long amount) {
// ...
balance += amount;
}
synchronized void withdraw(long amount) {
// ...
balance -= amount;
}
}
Should I add volatile to balance field?
No, compared with synchronized keyword, volatile is lightweight.
volatile can gurantee the reader thread always get fresh balance value, but it can not make balance += amount; atomic. synchronized can do both.
You don’t need volatile in the code shown, because the variable is used only within the synchronized methods. The synchronized methods make sure that the variable’s contents are visible and not stale, and also make sure that the operations performed within each synchronized method are not interfered with by concurrently running threads. The volatile keyword is redundant here, it only makes sure the variable’s contents are visible.
If you want the variable’s value to be visible to threads that don’t enter a synchronized instance method on this object (maybe you’d like it to be used in methods that don’t acquire a lock on the instance), then in that case keeping it volatile would make sense.
If you took away the synchronized keywords and left the variable volatile, you’d have a problem, because although volatile makes sure updates are visible it doesn’t make sure the updates are atomic. The += and -= operations here are not atomic and can be interfered with by concurrently-running threads.
Alternatively consider using an AtomicLong instead, in this example you might not need the synchronized keyword (depending on what the code in //... does). Methods like addAndGet perform their changes to the value stored atomically. For most things where you would have used volatile before, the Atomic classes can do a better job.

Doesn't "volatile" ensure that other threads see a consistent value for the variable? [duplicate]

How do atomic / volatile / synchronized work internally?
What is the difference between the following code blocks?
Code 1
private int counter;
public int getNextUniqueIndex() {
return counter++;
}
Code 2
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
Code 3
private volatile int counter;
public int getNextUniqueIndex() {
return counter++;
}
Does volatile work in the following way? Is
volatile int i = 0;
void incIBy5() {
i += 5;
}
equivalent to
Integer i = 5;
void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}
I think that two threads cannot enter a synchronized block at the same time... am I right? If this is true then how does atomic.incrementAndGet() work without synchronized? And is it thread-safe?
And what is the difference between internal reading and writing to volatile variables / atomic variables? I read in some article that the thread has a local copy of the variables - what is that?
You are specifically asking about how they internally work, so here you are:
No synchronization
private int counter;
public int getNextUniqueIndex() {
return counter++;
}
It basically reads value from memory, increments it and puts back to memory. This works in single thread but nowadays, in the era of multi-core, multi-CPU, multi-level caches it won't work correctly. First of all it introduces race condition (several threads can read the value at the same time), but also visibility problems. The value might only be stored in "local" CPU memory (some cache) and not be visible for other CPUs/cores (and thus - threads). This is why many refer to local copy of a variable in a thread. It is very unsafe. Consider this popular but broken thread-stopping code:
private boolean stopped;
public void run() {
while(!stopped) {
//do some work
}
}
public void pleaseStop() {
stopped = true;
}
Add volatile to stopped variable and it works fine - if any other thread modifies stopped variable via pleaseStop() method, you are guaranteed to see that change immediately in working thread's while(!stopped) loop. BTW this is not a good way to interrupt a thread either, see: How to stop a thread that is running forever without any use and Stopping a specific java thread.
AtomicInteger
private AtomicInteger counter = new AtomicInteger();
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
The AtomicInteger class uses CAS (compare-and-swap) low-level CPU operations (no synchronization needed!) They allow you to modify a particular variable only if the present value is equal to something else (and is returned successfully). So when you execute getAndIncrement() it actually runs in a loop (simplified real implementation):
int current;
do {
current = get();
} while(!compareAndSet(current, current + 1));
So basically: read; try to store incremented value; if not successful (the value is no longer equal to current), read and try again. The compareAndSet() is implemented in native code (assembly).
volatile without synchronization
private volatile int counter;
public int getNextUniqueIndex() {
return counter++;
}
This code is not correct. It fixes the visibility issue (volatile makes sure other threads can see change made to counter) but still has a race condition. This has been explained multiple times: pre/post-incrementation is not atomic.
The only side effect of volatile is "flushing" caches so that all other parties see the freshest version of the data. This is too strict in most situations; that is why volatile is not default.
volatile without synchronization (2)
volatile int i = 0;
void incIBy5() {
i += 5;
}
The same problem as above, but even worse because i is not private. The race condition is still present. Why is it a problem? If, say, two threads run this code simultaneously, the output might be + 5 or + 10. However, you are guaranteed to see the change.
Multiple independent synchronized
void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}
Surprise, this code is incorrect as well. In fact, it is completely wrong. First of all you are synchronizing on i, which is about to be changed (moreover, i is a primitive, so I guess you are synchronizing on a temporary Integer created via autoboxing...) Completely flawed. You could also write:
synchronized(new Object()) {
//thread-safe, SRSLy?
}
No two threads can enter the same synchronized block with the same lock. In this case (and similarly in your code) the lock object changes upon every execution, so synchronized effectively has no effect.
Even if you have used a final variable (or this) for synchronization, the code is still incorrect. Two threads can first read i to temp synchronously (having the same value locally in temp), then the first assigns a new value to i (say, from 1 to 6) and the other one does the same thing (from 1 to 6).
The synchronization must span from reading to assigning a value. Your first synchronization has no effect (reading an int is atomic) and the second as well. In my opinion, these are the correct forms:
void synchronized incIBy5() {
i += 5
}
void incIBy5() {
synchronized(this) {
i += 5
}
}
void incIBy5() {
synchronized(this) {
int temp = i;
i = temp + 5;
}
}
Declaring a variable as volatile means that modifying its value immediately affects the actual memory storage for the variable. The compiler cannot optimize away any references made to the variable. This guarantees that when one thread modifies the variable, all other threads see the new value immediately. (This is not guaranteed for non-volatile variables.)
Declaring an atomic variable guarantees that operations made on the variable occur in an atomic fashion, i.e., that all of the substeps of the operation are completed within the thread they are executed and are not interrupted by other threads. For example, an increment-and-test operation requires the variable to be incremented and then compared to another value; an atomic operation guarantees that both of these steps will be completed as if they were a single indivisible/uninterruptible operation.
Synchronizing all accesses to a variable allows only a single thread at a time to access the variable, and forces all other threads to wait for that accessing thread to release its access to the variable.
Synchronized access is similar to atomic access, but the atomic operations are generally implemented at a lower level of programming. Also, it is entirely possible to synchronize only some accesses to a variable and allow other accesses to be unsynchronized (e.g., synchronize all writes to a variable but none of the reads from it).
Atomicity, synchronization, and volatility are independent attributes, but are typically used in combination to enforce proper thread cooperation for accessing variables.
Addendum (April 2016)
Synchronized access to a variable is usually implemented using a monitor or semaphore. These are low-level mutex (mutual exclusion) mechanisms that allow a thread to acquire control of a variable or block of code exclusively, forcing all other threads to wait if they also attempt to acquire the same mutex. Once the owning thread releases the mutex, another thread can acquire the mutex in turn.
Addendum (July 2016)
Synchronization occurs on an object. This means that calling a synchronized method of a class will lock the this object of the call. Static synchronized methods will lock the Class object itself.
Likewise, entering a synchronized block requires locking the this object of the method.
This means that a synchronized method (or block) can be executing in multiple threads at the same time if they are locking on different objects, but only one thread can execute a synchronized method (or block) at a time for any given single object.
volatile:
volatile is a keyword. volatile forces all threads to get latest value of the variable from main memory instead of cache. No locking is required to access volatile variables. All threads can access volatile variable value at same time.
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.
This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
When to use: One thread modifies the data and other threads have to read latest value of data. Other threads will take some action but they won't update data.
AtomicXXX:
AtomicXXX classes support lock-free thread-safe programming on single variables. These AtomicXXX classes (like AtomicInteger) resolves memory inconsistency errors / side effects of modification of volatile variables, which have been accessed in multiple threads.
When to use: Multiple threads can read and modify data.
synchronized:
synchronized is keyword used to guard a method or code block. By making method as synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
When to use: Multiple threads can read and modify data. Your business logic not only update the data but also executes atomic operations
AtomicXXX is equivalent of volatile + synchronized even though the implementation is different. AmtomicXXX extends volatile variables + compareAndSet methods but does not use synchronization.
Related SE questions:
Difference between volatile and synchronized in Java
Volatile boolean vs AtomicBoolean
Good articles to read: ( Above content is taken from these documentation pages)
https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
I know that two threads can not enter in Synchronize block at the same time
Two thread cannot enter a synchronized block on the same object twice. This means that two threads can enter the same block on different objects. This confusion can lead to code like this.
private Integer i = 0;
synchronized(i) {
i++;
}
This will not behave as expected as it could be locking on a different object each time.
if this is true than How this atomic.incrementAndGet() works without Synchronize ?? and is thread safe ??
yes. It doesn't use locking to achieve thread safety.
If you want to know how they work in more detail, you can read the code for them.
And what is difference between internal reading and writing to Volatile Variable / Atomic Variable ??
Atomic class uses volatile fields. There is no difference in the field. The difference is the operations performed. The Atomic classes use CompareAndSwap or CAS operations.
i read in some article that thread has local copy of variables what is that ??
I can only assume that it referring to the fact that each CPU has its own cached view of memory which can be different from every other CPU. To ensure that your CPU has a consistent view of data, you need to use thread safety techniques.
This is only an issue when memory is shared at least one thread updates it.
Synchronized Vs Atomic Vs Volatile:
Volatile and Atomic is apply only on variable , While Synchronized apply on method.
Volatile ensure about visibility not atomicity/consistency of object , While other both ensure about visibility and atomicity.
Volatile variable store in RAM and it’s faster in access but we can’t achive Thread safety or synchronization whitout synchronized keyword.
Synchronized implemented as synchronized block or synchronized method while both not. We can thread safe multiple line of code with help of synchronized keyword while with both we can’t achieve the same.
Synchronized can lock the same class object or different class object while both can’t.
Please correct me if anything i missed.
A volatile + synchronization is a fool proof solution for an operation(statement) to be fully atomic which includes multiple instructions to the CPU.
Say for eg:volatile int i = 2; i++, which is nothing but i = i + 1; which makes i as the value 3 in the memory after the execution of this statement.
This includes reading the existing value from memory for i(which is 2), load into the CPU accumulator register and do with the calculation by increment the existing value with one(2 + 1 = 3 in accumulator) and then write back that incremented value back to the memory. These operations are not atomic enough though the value is of i is volatile. i being volatile guarantees only that a SINGLE read/write from memory is atomic and not with MULTIPLE. Hence, we need to have synchronized also around i++ to keep it to be fool proof atomic statement. Remember the fact that a statement includes multiple statements.
Hope the explanation is clear enough.
The Java volatile modifier is an example of a special mechanism to guarantee that communication happens between threads. When one thread writes to a volatile variable, and another thread sees that write, the first thread is telling the second about all of the contents of memory up until it performed the write to that volatile variable.
Atomic operations are performed in a single unit of task without interference from other operations. Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.

How to synchronize getter and setter in threading

public class IntermediateMessage {
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock read = readWriteLock.readLock();
private final Lock write = readWriteLock.writeLock();
private volatile double ratio;
public IntermediateMessage(){
this.ratio=1.0d;
}
public IntermediateMessage(double ratio){
this.ratio = ratio;
}
public double getRatio(){
read.lock();
try{
return this.ratio;
}
finally{
read.unlock();
}
}
public void setRatio(double ratio){
write.lock();
try{
this.ratio = ratio;
}
finally{
write.unlock();
}
}
}
I have this object. I have an instance of this object in my application and one thread is writing to the ratio variable while the other threads are reading the ratio. Is this correct way to protect the ratio variable? Do I need to declare ratio as volatile?
Do you need locking at all? Most likely not, according to the limited requirements you've described. But read this to be sure...
You have just one thread writing.
This means that the variable value can never be "out of date" due to competing writers "clobbering" one another (no possible race condition). So no locking is required to give integrity when considering the individual variable in isolation.
You have not mentioned whether some form of atomic, consistent modification of multiple variables is required. I assume it isn't.
IF ratio must always be consistent with other variables (e.g. in other objects) - i.e. if a set of variables must change in synchrony as a group with no one reading just part of the changes - then locking is required to give atomic consistency to the set of variables. Then consistent variables must be modified together within in a single locked region and readers must obtain the same lock before reading any of these set of variables (waiting in a blocked state, if necessary).
IF ratio can be changed at any time as a lone variable and need not be kept consistent with other variables, then no locking is required give atomic consistency to a set of variables.
Do you need the volatile modifier? Well, yes!
You have multiple threads reading.
The variable can change at any moment, including an instant before it's about to be read.
The volatile modifier is used in multi-threaded apps to guarantee that the value read by "readers" always matches the value written by "writers".
You are doing some overkill on the synchronization that is going to cause some inefficiency.
The java keyword "volatile" means that variable won't be cached, and that it will have synchronized access for multiple threads.
So you are locking a variable that is already by default synchronized.
So you should either remove the volatile keyword, or remove the reentrant locks. Probably the volatile as you will be more efficient with multiple reads the way you are currently synchronizing.
For reading/writing a primitive value, volatile alone is sufficient.
Provided two threads are trying to read and write on the same object and you want the data integrity to be mantained. Just make your getter and setter synchronized. When a method is synchonized, only one thread will be able to call a synchronize method. While one thread is executing one of the synchronized method, no other thread will be able to call any of the synchronized method. So in your case if you have your get & set method synchronized, you can be sure if a thread is reading/writing no other thread can do the reading/writing.
Hope it helps!
Make ratio final and it will be thread safe.

Should getters and setters be synchronized?

private double value;
public synchronized void setValue(double value) {
this.value = value;
}
public double getValue() {
return this.value;
}
In the above example is there any point in making the getter synchronized?
I think its best to cite Java Concurrency in Practice here:
It is a common mistake to assume that synchronization needs to be used only when writing to shared variables; this is simply not true.
For each mutable state variable that may be accessed by more than one
thread, all accesses to that variable must be performed with the same
lock held. In this case, we say that the variable is guarded by that
lock.
In the absence of synchronization, the compiler, processor, and runtime can do some downright weird things to the order in which operations appear to execute. Attempts to reason about the order in which memory actions "must" happen in insufflciently synchronized multithreaded programs will almost certainly be incorrect.
Normally, you don't have to be so careful with primitives, so if this would be an int or a boolean it might be that:
When a thread reads a variable without synchronization, it may see a
stale value, but at least it sees a value that was actually placed
there by some thread rather than some random value.
This, however, is not true for 64-bit operations, for instance on long or double if they are not declared volatile:
The Java Memory Model requires fetch and
store operations to be atomic, but for nonvolatile long and double
variables, the JVM is permitted to treat a 64-bit read or write as two
separate 32-bit operations. If the reads and writes occur in different
threads, it is therefore possible to read a nonvolatile long and get
back the high 32 bits of one value and the low 32 bits of another.
Thus, even if you don't care about stale values, it is not safe to use
shared mutable long and double variables in multithreaded programs
unless they are declared volatile or guarded by a lock.
Let me show you by example what is a legal way for a JIT to compile your code. You write:
while (myBean.getValue() > 1.0) {
// perform some action
Thread.sleep(1);
}
JIT compiles:
if (myBean.getValue() > 1.0)
while (true) {
// perform some action
Thread.sleep(1);
}
In just slightly different scenarios even the Java compiler could prouduce similar bytecode (it would only have to eliminate the possibility of dynamic dispatch to a different getValue). This is a textbook example of hoisting.
Why is this legal? The compiler has the right to assume that the result of myBean.getValue() can never change while executing above code. Without synchronized it is allowed to ignore any actions by other threads.
The reason here is to guard against any other thread updating the value when a thread is reading and thus avoid performing any action on stale value.
Here get method will acquire intrinsic lock on "this" and thus any other thread which might attempt to set/update using setter method will have to wait to acquire lock on "this" to enter the setter method which is already acquired by thread performing get.
This is why its recommended to follow the practice of using same lock when performing any operation on a mutable state.
Making the field volatile will work here as there are no compound statements.
It is important to note that synchronized methods use intrinsic lock which is "this". So get and set both being synchronized means any thread entering the method will have to acquire lock on this.
When performing non atomic 64 bit operations special consideration should be taken. Excerpts from Java Concurrency In Practice could be of help here to understand the situation -
"The Java Memory Model requires fetch and store operations to be atomic, but for non-volatile long and double variables, the JVM is permitted to treat a 64 bit read or write as two separate 32
bit operations. If the reads and writes occur in different threads, it is therefore possible to read a non-volatile long and get back the high 32 bits of one value and the low 32 bits of another. Thus, even if you don't care about stale values, it
is not safe to use shared mutable long and double variables in multi-threaded programs unless they are declared
volatile or guarded by a lock."
Maybe for someone this code looks awful, but it works very well.
private Double value;
public void setValue(Double value){
updateValue(value, true);
}
public Double getValue(){
return updateValue(value, false);
}
private double updateValue(Double value,boolean set){
synchronized(MyClass.class){
if(set)
this.value = value;
return value;
}
}

What is the difference between atomic / volatile / synchronized?

How do atomic / volatile / synchronized work internally?
What is the difference between the following code blocks?
Code 1
private int counter;
public int getNextUniqueIndex() {
return counter++;
}
Code 2
private AtomicInteger counter;
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
Code 3
private volatile int counter;
public int getNextUniqueIndex() {
return counter++;
}
Does volatile work in the following way? Is
volatile int i = 0;
void incIBy5() {
i += 5;
}
equivalent to
Integer i = 5;
void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}
I think that two threads cannot enter a synchronized block at the same time... am I right? If this is true then how does atomic.incrementAndGet() work without synchronized? And is it thread-safe?
And what is the difference between internal reading and writing to volatile variables / atomic variables? I read in some article that the thread has a local copy of the variables - what is that?
You are specifically asking about how they internally work, so here you are:
No synchronization
private int counter;
public int getNextUniqueIndex() {
return counter++;
}
It basically reads value from memory, increments it and puts back to memory. This works in single thread but nowadays, in the era of multi-core, multi-CPU, multi-level caches it won't work correctly. First of all it introduces race condition (several threads can read the value at the same time), but also visibility problems. The value might only be stored in "local" CPU memory (some cache) and not be visible for other CPUs/cores (and thus - threads). This is why many refer to local copy of a variable in a thread. It is very unsafe. Consider this popular but broken thread-stopping code:
private boolean stopped;
public void run() {
while(!stopped) {
//do some work
}
}
public void pleaseStop() {
stopped = true;
}
Add volatile to stopped variable and it works fine - if any other thread modifies stopped variable via pleaseStop() method, you are guaranteed to see that change immediately in working thread's while(!stopped) loop. BTW this is not a good way to interrupt a thread either, see: How to stop a thread that is running forever without any use and Stopping a specific java thread.
AtomicInteger
private AtomicInteger counter = new AtomicInteger();
public int getNextUniqueIndex() {
return counter.getAndIncrement();
}
The AtomicInteger class uses CAS (compare-and-swap) low-level CPU operations (no synchronization needed!) They allow you to modify a particular variable only if the present value is equal to something else (and is returned successfully). So when you execute getAndIncrement() it actually runs in a loop (simplified real implementation):
int current;
do {
current = get();
} while(!compareAndSet(current, current + 1));
So basically: read; try to store incremented value; if not successful (the value is no longer equal to current), read and try again. The compareAndSet() is implemented in native code (assembly).
volatile without synchronization
private volatile int counter;
public int getNextUniqueIndex() {
return counter++;
}
This code is not correct. It fixes the visibility issue (volatile makes sure other threads can see change made to counter) but still has a race condition. This has been explained multiple times: pre/post-incrementation is not atomic.
The only side effect of volatile is "flushing" caches so that all other parties see the freshest version of the data. This is too strict in most situations; that is why volatile is not default.
volatile without synchronization (2)
volatile int i = 0;
void incIBy5() {
i += 5;
}
The same problem as above, but even worse because i is not private. The race condition is still present. Why is it a problem? If, say, two threads run this code simultaneously, the output might be + 5 or + 10. However, you are guaranteed to see the change.
Multiple independent synchronized
void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}
Surprise, this code is incorrect as well. In fact, it is completely wrong. First of all you are synchronizing on i, which is about to be changed (moreover, i is a primitive, so I guess you are synchronizing on a temporary Integer created via autoboxing...) Completely flawed. You could also write:
synchronized(new Object()) {
//thread-safe, SRSLy?
}
No two threads can enter the same synchronized block with the same lock. In this case (and similarly in your code) the lock object changes upon every execution, so synchronized effectively has no effect.
Even if you have used a final variable (or this) for synchronization, the code is still incorrect. Two threads can first read i to temp synchronously (having the same value locally in temp), then the first assigns a new value to i (say, from 1 to 6) and the other one does the same thing (from 1 to 6).
The synchronization must span from reading to assigning a value. Your first synchronization has no effect (reading an int is atomic) and the second as well. In my opinion, these are the correct forms:
void synchronized incIBy5() {
i += 5
}
void incIBy5() {
synchronized(this) {
i += 5
}
}
void incIBy5() {
synchronized(this) {
int temp = i;
i = temp + 5;
}
}
Declaring a variable as volatile means that modifying its value immediately affects the actual memory storage for the variable. The compiler cannot optimize away any references made to the variable. This guarantees that when one thread modifies the variable, all other threads see the new value immediately. (This is not guaranteed for non-volatile variables.)
Declaring an atomic variable guarantees that operations made on the variable occur in an atomic fashion, i.e., that all of the substeps of the operation are completed within the thread they are executed and are not interrupted by other threads. For example, an increment-and-test operation requires the variable to be incremented and then compared to another value; an atomic operation guarantees that both of these steps will be completed as if they were a single indivisible/uninterruptible operation.
Synchronizing all accesses to a variable allows only a single thread at a time to access the variable, and forces all other threads to wait for that accessing thread to release its access to the variable.
Synchronized access is similar to atomic access, but the atomic operations are generally implemented at a lower level of programming. Also, it is entirely possible to synchronize only some accesses to a variable and allow other accesses to be unsynchronized (e.g., synchronize all writes to a variable but none of the reads from it).
Atomicity, synchronization, and volatility are independent attributes, but are typically used in combination to enforce proper thread cooperation for accessing variables.
Addendum (April 2016)
Synchronized access to a variable is usually implemented using a monitor or semaphore. These are low-level mutex (mutual exclusion) mechanisms that allow a thread to acquire control of a variable or block of code exclusively, forcing all other threads to wait if they also attempt to acquire the same mutex. Once the owning thread releases the mutex, another thread can acquire the mutex in turn.
Addendum (July 2016)
Synchronization occurs on an object. This means that calling a synchronized method of a class will lock the this object of the call. Static synchronized methods will lock the Class object itself.
Likewise, entering a synchronized block requires locking the this object of the method.
This means that a synchronized method (or block) can be executing in multiple threads at the same time if they are locking on different objects, but only one thread can execute a synchronized method (or block) at a time for any given single object.
volatile:
volatile is a keyword. volatile forces all threads to get latest value of the variable from main memory instead of cache. No locking is required to access volatile variables. All threads can access volatile variable value at same time.
Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable.
This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
When to use: One thread modifies the data and other threads have to read latest value of data. Other threads will take some action but they won't update data.
AtomicXXX:
AtomicXXX classes support lock-free thread-safe programming on single variables. These AtomicXXX classes (like AtomicInteger) resolves memory inconsistency errors / side effects of modification of volatile variables, which have been accessed in multiple threads.
When to use: Multiple threads can read and modify data.
synchronized:
synchronized is keyword used to guard a method or code block. By making method as synchronized has two effects:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
When to use: Multiple threads can read and modify data. Your business logic not only update the data but also executes atomic operations
AtomicXXX is equivalent of volatile + synchronized even though the implementation is different. AmtomicXXX extends volatile variables + compareAndSet methods but does not use synchronization.
Related SE questions:
Difference between volatile and synchronized in Java
Volatile boolean vs AtomicBoolean
Good articles to read: ( Above content is taken from these documentation pages)
https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html
I know that two threads can not enter in Synchronize block at the same time
Two thread cannot enter a synchronized block on the same object twice. This means that two threads can enter the same block on different objects. This confusion can lead to code like this.
private Integer i = 0;
synchronized(i) {
i++;
}
This will not behave as expected as it could be locking on a different object each time.
if this is true than How this atomic.incrementAndGet() works without Synchronize ?? and is thread safe ??
yes. It doesn't use locking to achieve thread safety.
If you want to know how they work in more detail, you can read the code for them.
And what is difference between internal reading and writing to Volatile Variable / Atomic Variable ??
Atomic class uses volatile fields. There is no difference in the field. The difference is the operations performed. The Atomic classes use CompareAndSwap or CAS operations.
i read in some article that thread has local copy of variables what is that ??
I can only assume that it referring to the fact that each CPU has its own cached view of memory which can be different from every other CPU. To ensure that your CPU has a consistent view of data, you need to use thread safety techniques.
This is only an issue when memory is shared at least one thread updates it.
Synchronized Vs Atomic Vs Volatile:
Volatile and Atomic is apply only on variable , While Synchronized apply on method.
Volatile ensure about visibility not atomicity/consistency of object , While other both ensure about visibility and atomicity.
Volatile variable store in RAM and it’s faster in access but we can’t achive Thread safety or synchronization whitout synchronized keyword.
Synchronized implemented as synchronized block or synchronized method while both not. We can thread safe multiple line of code with help of synchronized keyword while with both we can’t achieve the same.
Synchronized can lock the same class object or different class object while both can’t.
Please correct me if anything i missed.
A volatile + synchronization is a fool proof solution for an operation(statement) to be fully atomic which includes multiple instructions to the CPU.
Say for eg:volatile int i = 2; i++, which is nothing but i = i + 1; which makes i as the value 3 in the memory after the execution of this statement.
This includes reading the existing value from memory for i(which is 2), load into the CPU accumulator register and do with the calculation by increment the existing value with one(2 + 1 = 3 in accumulator) and then write back that incremented value back to the memory. These operations are not atomic enough though the value is of i is volatile. i being volatile guarantees only that a SINGLE read/write from memory is atomic and not with MULTIPLE. Hence, we need to have synchronized also around i++ to keep it to be fool proof atomic statement. Remember the fact that a statement includes multiple statements.
Hope the explanation is clear enough.
The Java volatile modifier is an example of a special mechanism to guarantee that communication happens between threads. When one thread writes to a volatile variable, and another thread sees that write, the first thread is telling the second about all of the contents of memory up until it performed the write to that volatile variable.
Atomic operations are performed in a single unit of task without interference from other operations. Atomic operations are necessity in multi-threaded environment to avoid data inconsistency.

Categories