Small question about memory visibility.
CodeSample1:
class CustomLock {
private boolean locked = false;
public boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
This code is prone to bugs in a multi-threaded environment, first because of the "if-then-act" which is not atomic, and second because of potential memory visibility issues where for example threadA sets the field to true, but threadB that later wishes to read the field's value might not see that, and still see the value false.
The simplest solution is to use the synchronized keyword, as in CodeSample2.
CodeSample2:
class CustomLock {
private boolean locked = false;
public synchronized boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
Now what if I wish to use an atomic variable, and for the example, an AtomicBoolean (question applies to all atomic variables),
CodeSample3:
public static class CustomLock {
private AtomicBoolean locked = new AtomicBoolean(false);
public boolean lock() {
return locked.compareAndSet(false, true);
}
}
Better performance considerations aside, we can see that now we've implemented similar logic to the "if-then-act" from CodeSample1, using AtomicBoolean.
It doesn't really matter what the code does logically, the question I have is what if 2 threads invoke the lock() method in CodeSample3 right about the same time, while it's clear that any write operation to the field will now be done atomically, does the use of AtomicBoolean also guarantees memory visibility?
Sorry for the long story, just wanted to make sure I'm coming across as clear as possible, Thanks guys...
Yes, according to the javadocs it guarantees:
compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.
the question I have is what if 2 threads invoke the lock() method in CodeSample3 right about the same time, while it's clear that any write operation to the field will now be done atomically, does the use of AtomicBoolean also guarantees memory visibility?
For AtomicBoolean to handle multiple operations from different threads at the same time it has to guarantee memory visibility. It can make the guarantee because it wraps a volatile field. It is the language semantics of the volatile which ensures that memory barriers are crossed so that multiple threads see the most up to date value and that any updates will be published to main memory.
Btw, your lock(...) method should ready be tryLock(...) because it might not get the lock.
Related
I'm exploring an example of a simple android game and I have a question about its synchronization logic.
Given two fields:
private boolean mRun = false;
private final Object mRunLock = new Object();
Method setRunning in a worker thread class:
public void setRunning(boolean b) {
synchronized (mRunLock) {
mRun = b;
}
}
And method run in the same class:
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) updatePhysics();
synchronized (mRunLock) {
if (mRun) doDraw(c);
}
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
Is it correct to not synchronize mRun in the while statement? I think setRunning might potencially be called while mRun is being checked for true.
I don't think the code is correct.
You should probably do something like:
while (true) {
synchronized (mRunLock) {
if (mRun) break;
}
// ...
}
Without this, you don't have a guarantee that writing to mRun happens-before the read in the condition.
It will sort-of work without it, because you are reading mRun inside a synchronized block inside the loop; provided that read is executed, the value will be updated. But the value you read in the loop expression on the next iteration could be the same value as was read on the previous iteration in the synchronized (mRunLock) { if (mRun) doDraw(c); }.
Critically, it isn't guaranteed to read an up-to-date value on the initial iteration. If false is cached, the loop won't execute.
Making mRun volatile would be easier than using synchronization, though.
You need to keep the 'synchronized' statements. If you don't (though note that android, which isn't really java, may not be adhering to the same memory model as actual java), then any thread is free to make a temporary clone for any field of any instance it wants, and synchronize any writes to the clone at some undefined later point in time with any other thread's clone.
To avoid the issues with these 'clones'*, you need to establish CBCA relationships ("comes before/comes after") - if the thread model ensures that line X in thread A definitely ran after line Y in thread B, then any field writes done by line Y will guaranteed be visible in line X.
In other words, with the synchronized statements, if the mRunLock lock in your run() method has to 'wait' for the setRunning method to finish running, you just established a CBCA relationship between the two, and it's crucial because that means the mRun write done by setRunning is now visible. If you didn't, it may be visible, it may not be, it depends on the chip in your phone and the phase of the moon.
Note that boolean writes are otherwise atomic. So it's not so much about any issues that would occur if you read whilst the field is being written (that is not a problem in itself if the field's type is decreed as being atomic, which all primitives other than double and long are), it's ensuring visibility of any changes.
In plain jane java you'd probably use an AtomicBoolean for this and avoid using any synchronized anything. Note also that nesting synchronized() on different locks (you lock on mSurfaceHolder, and then lock on mRunLock) can lead to deadlocks if any code does it 'in reverse' (locks on mRunLock first, then locks on mSurfaceHolder).
Are you running into any problems with this code, or just wondering 'is it correct'? If the latter: Yes, it is correct.
*) Whilst this clone thing sounds tedious and errorprone, the only alternative is that any field write by any thread is immediately visible by any other thread. That would slow everything waaaaay down; the VM has no idea which writes have the potential to be read soon by another thread, and if you know anything about modern CPU architecture, each core has its own cache that is orders of magnitude (100 to 1000 times!) faster than system memory. This alternative of 'all writes must always be visible everywhere' would pretty much mean that fields can never be in any caches ever. That'd be disastrous for performance. This memory model is therefore basically a necessary evil. There are languages that don't have it; they tend to be orders of magnitude slower than java.
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.
I read some java code, and found these functions:
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
I wonder if synchronization makes any sense here, or just author didn't understand the need for synchronized keyword?
I'd suppose that synchronized is useless here. Or am I mistaken?
The keyword synchronized is one way of ensuring thread-safety. Beware: there's (way) more to thread-safety than deadlocks, or missing updates because of two threads incrementing an int without synchronization.
Consider the following class:
class Connection {
private boolean connected;
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
}
If multiple threads share an instance of Connection and one thread calls setConnected(true), without synchronized it is possible that other threads keep seeing isConnected() == false. The synchronized keyword guarantees that all threads sees the current value of the field.
In more technical terms, the synchronized keyword ensures a memory barrier (hint: google that).
In more details: every write made before releasing a monitor (ie, before leaving a synchronized block) is guaranteed to be seen by every read made after acquiring the same monitor (ie, after entering a block synchronizing on the same object). In Java, there's something called happens-before (hint: google that), which is not as trivial as "I wrote the code in this order, so things get executed in this order". Using synchronized is a way to establish a happens-before relationship and guarantee that threads see the memory as you would expect them to see.
Another way to achieve the same guarantees, in this case, would be to eliminate the synchronized keyword and mark the field volatile. The guarantees provided by volatile are as follows: all writes made by a thread before a volatile write are guaranteed to be visible to a thread after a subsequent volatile read of the same field.
As a final note, in this particular case it might be better to use a volatile field instead of synchronized accessors, because the two approaches provide the same guarantees and the volatile-field approach allows simultaneous accesses to the field from different threads (which might improve performance if the synchronized version has too much contention).
Synchronization is needed here to prevent memory consistency errors, see http://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html. Though in this concrete case volatile would be much more efficient solution
private volatile boolean connected;
void setConnected(boolean connected){
this.connected = connected;
}
boolean isConnected(){
return connected;
}
The author has probably designed the code with a multi-threaded approach in mind. This means that the methods are synchronized and more than one thread will not be able to access the synchronized code at the same time on the same object instance.
I have the following code:
public class Simulation
{
public static volatile boolean IS_EVEN_TICK;
}
and the following in another (runnable) class:
public void run()
{
while (true)
{
// flip the "even/uneven tick" switch
Simulation.IS_EVEN_TICK = !Simulation.IS_EVEN_TICK;
}
}
As far as I understand it this is generally not thread-safe, because the write to Simulation.IS_EVEN_TICK depends on the current value of that variable. However this thread is the only thread that ever writes to the variable, all other threads will only read the variable (if they access it at all).
Is the variable being volatile enough to make sure that all threads read the right value from it or do I need to synchronize the access to the variable nonetheless?
However this thread is the only thread that ever writes to the variable... Is the variable being volatile enough to make sure that all threads read the right value from it.
If there is only one writer then there is no race condition. You do not need to synchronize across the variable.
You might consider using an AtomicBoolean but it does not support a toggle() method so if you had multiple writers toggling the value, you would have to do something like the following:
private final AtomicBoolean isEvenTick = new AtomicBoolean();
...
boolean currentValue;
do {
currentValue = isEvenTick.get();
} while (!isEvenTick.compareAndSet(currentValue, !currentValue);
try to read specification and understand JMM, if your variable volatile it means that variable will be created directly in heap and no one processor does not copy that value to own cache.
Volatile fields are special fields which are used for communicating state between threads. Each read of a volatile will see the last write to that volatile by any thread; in effect, they are designated by the programmer as fields for which it is never acceptable to see a "stale" value as a result of caching or reordering
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.