Related
I read it from Java Concurrency in Practice, that it is bad to share variables in threads without synchronisation. However, for some examples as following which only have one read thread and one write thread, I can't find errors in it. From my perspective, the result for the following program will definitely terminate and print 42 because ReaderThread can go through only when ready becomes true, and that means number is 42. Could somebody give me some explanation why I am wrong?
public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
Since ready isn't volatile, there's no guarantee that ReaderThread will see that your main thread has changed it. When you mark ready as volatile, all writes from one thread will be seen in other threads reading it.
You always need some sort of synchronization / visibility control when communicating between threads. Whether it's volatile, explicitly using synchronized or using the java.util.concurrent.* classes.
You don't need synchronization (e.g., synchronized) in your example (though you do need volatile, more below) because reads and writes of boolean and int variables are always atomic. Which is to say, a thread can't be part-way through writing to a boolean (or int) variable when another thread comes along and reads it, getting garbage. The value being written by one thread is always fully written before another thread can read it. (This is not true of non-volatile double or long variables; it would be entirely possible for a thread to read garbage if it happened to read in the middle of another thread's write to a long or double if they aren't marked volatile.)
But you do need volatile, because each thread can have its own copy of the variables, and potentially can keep using its own copy for a long period of time. So it's entirely possible for your reader thread to wait forever, because it keeps re-reading its own copy of ready which stays false even though your main thread writes true to its copy of ready. It's also possible for your reader thread to see ready become true but keep reading its own copy of number, and so print 0 instead of 42.
You would need to use synchronized if you were modifying the state of an object that doesn't guarantee thread-safe access. For instance, if you were adding to a Map or List. That's because there are multiple operations involved, and it's essential to prevent one thread from reading a half-complete change another thread is making.
Other classes, such as those in java.util.concurrent, offer classes with thread-safe access semantics.
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 have few doubts about synchronized blocks.
Before my questions I would like to share the answers from another related post Link for Answer to related question. I quote Peter Lawrey from the same answer.
synchronized ensures you have a consistent view of the data. This means you will read the latest value and other caches will get the
latest value. Caches are smart enough to talk to each other via a
special bus (not something required by the JLS, but allowed) This
bus means that it doesn't have to touch main memory to get a
consistent view.
If you only use synchronized, you wouldn't need volatile. Volatile is useful if you have a very simple operation for which synchronized
would be overkill.
In reference to above I have three questions below :
Q1. Suppose in a multi threaded application there is an object or a primitive instance field being only read in a synchronized block (write may be happening in some other method without synchronization). Also Synchronized block is defined upon some other Object. Does declaring it volatile (even if it is read inside Synchronized block only) makes any sense ?
Q2. I understand the value of the states of the object upon which Synchronization has been done is consistent. I am not sure for the state of other objects and primitive fields being read in side the Synchronized block. Suppose changes are made without obtaining a lock but reading is done by obtaining a lock. Does state of all the objects and value of all primitive fields inside a Synchronized block will have consistent view always. ?
Q3. [Update] : Will all fields being read in a synchronized block will be read from main memory regardless of what we lock on ? [answered by CKing]
I have a prepared a reference code for my questions above.
public class Test {
private SomeClass someObj;
private boolean isSomeFlag;
private Object lock = new Object();
public SomeClass getObject() {
return someObj;
}
public void setObject(SomeClass someObj) {
this.someObj = someObj;
}
public void executeSomeProcess(){
//some process...
}
// synchronized block is on a private someObj lock.
// inside the lock method does the value of isSomeFlag and state of someObj remain consistent?
public void someMethod(){
synchronized (lock) {
while(isSomeFlag){
executeSomeProcess();
}
if(someObj.isLogicToBePerformed()){
someObj.performSomeLogic();
}
}
}
// this is method without synchronization.
public void setSomeFlag(boolean isSomeFlag) {
this.isSomeFlag = isSomeFlag;
}
}
The first thing you need to understand is that there is a subtle difference between the scenario being discussed in the linked answer and the scenario you are talking about. You speak about modifying a value without synchronization whereas all values are modified within a synchronized context in the linked answer. With this understanding in mind, let's address your questions :
Q1. Suppose in a multi threaded application there is an object or a primitive instance field being only read in a synchronized block (write may be happening in some other method without synchronization). Also Synchronized block is defined upon some other Object. Does declaring it volatile (even if it is read inside Synchronized block only) makes any sense ?
Yes it does make sense to declare the field as volatile. Since the write is not happening in a synchronized context, there is no guarantee that the writing thread will flush the newly updated value to main memory. The reading thread may still see inconsistent values because of this.
Suppose changes are made without obtaining a lock but reading is done by obtaining a lock. Does state of all the objects and value of all primitive fields inside a Synchronized block will have consistent view always. ?
The answer is still no. The reasoning is the same as above.
Bottom line : Modifying values outside synchronized context will not ensure that these values get flushed to main memory. (as the reader thread may enter the synchronized block before the writer thread does) Threads that read these values in a synchronized context may still end up reading older values even if they get these values from the main memory.
Note that this question talks about primitives so it is also important to understand that Java provides Out-of-thin-air safety for 32-bit primitives (all primitives except long and double) which means that you can be assured that you will atleast see a valid value (if not consistent).
All synchronized does is capture the lock of the object that it is synchronized on. If the lock is already captured, it will wait for its release. It does not in any way assert that that object's internal fields won't change. For that, there is volatile
When you synchronize on an object monitor A, it is guaranteed that another thread synchronizing on the same monitor A afterwards will see any changes made by the first thread to any object. That's the visibility guarantee provided by synchronized, nothing more.
A volatile variable guarantees visibility (for the variable only, a volatile HashMap doesn't mean the contents of the map would be visible) between threads regardless of any synchronized blocks.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When exactly do you use the volatile keyword in Java?
When and why volatile modifier is required in java?
I am interested in seeing a real world usage of a volatile modified primitive or object reference.
volatile modifier will tell the JVM to be cautious of the threads which runs concurrently. Essentially, volatile is used to indicate that a variable's value will be modified by different threads.
Declaring a volatile Java variable means:
The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
We say "acts as though" in the second point, because to the programmer at least (and probably in most JVM implementations) there is no actual lock object involved.
The volatile modifier tells the compiler that the variable modified by volatile can be changed unexpectedly by other parts of your program. One of these situations involves multithreaded programs.
In a multithreaded program, sometimes, two or more threads share the same instance variable. For efficiency considerations, each thread can keep its own, private copy of such a shared variable.
The real (or master) copy of the variable is updated at various times, such as when a synchronized method is entered. While this approach works fine, it may be inefficient at times. In some cases, all that really matters is that the master copy of a variable always reflects its current state.
To ensure this, simply specify the variable as volatile, which tells the compiler that it must always use the master copy of a volatile variable (or, at least, always keep any private copies up to date with the master copy, and vice versa). Also, accesses to the master variable must be executed in the precise order in which they are executed on any private copy.
If you are working with the multi-threaded programming, the volatile keyword will be more useful. When multiple
threads using the same variable, each thread will have its own copy of the local cache for that variable. So, when it’s
updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which
is using the same variable doesn’t know anything about the values changed by the another thread. To avoid this problem,
if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the
values, it is updated to the main memory. So, other threads can access the updated value.
Declaring a variable volatile means
There will be no cache maintained means all the changes made in main memory.
Access to this variable acts as synchronized block, even though it is in synchronized unit.
Example -
public class Snippet implements Runnable{
volatile int num =0;
public void run(){
Thread t = Thread.currentThread();
String name = t.getName();
if(name.equals("Thread1")){
num=10;
}
else{
System.out.println("value of num is :"+num);
}
}
public static void main(String args[]) throws InterruptedException{
Runnable r = new Snippet();
Thread t1 = new Thread(r);
t1.setName("Thread1");
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(r);
t2.setName("Thread2");
t2.start();
}
}
(This answer assumes Java 5+ -- before that, volatile had weaker guarantees.)
It's useful when you want to ensure a memory barrier, aka a formal "happens-before" relationship, between a write to a field and a subsequent read to that field by a separate thread. Synchronization can also give you that relationship, as well as other multithreading guarantees, but it's a tad slower and can create synchronization bottlenecks.
One use case is in concurrent collection classes (like ConcurrentHashMap, or LinkedBlockingQueue) where, in conjunction with things like atomic compare-and-set (CAS) operations, you can write correct thread-safe code without having to use synchronized.
You got good answers for the first question. The second one:
Can any one give me real time scenario of it
IMO, you should never ever you volatile. There are better tools for multithreaded apps. It's a bit bizarre that such a high level language has this keyword. Here is a good read (It's about C#, but Java is similar in this matter).
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.