Its very important question from interview perspective.
- Volatile can be used as a keyword against the variable, we cannot use volatile against method declaration.
volatile void method1(){} //it’s illegal, compilation error.
volatile int i; //legal
While synchronization can be used in method declaration or we can create synchronization blocks. Variables cannot be synchronized.
Synchronized method:
synchronized void method2(){} //legal
Synchronized block:
void method2(){
synchronized (this) {
//code inside synchronized block.
}
}
Synchronized variable (illegal):
synchronized int i; //it’s illegal, compilation error.
- Volatile does not acquire any lock on variable or object, but Synchronization acquires lock on method or block in which it is used.
- Volatile variables are not cached, but variables used inside synchronized method or block are cached.
- When volatile is used will never create deadlock in program, as volatile never obtains any kind of lock . But in case if synchronization is not done properly, we might end up creating dedlock in program.
- Synchronization may cost us performance issues, as one thread might be waiting for another thread to release lock on object. But volatile is never expensive in terms of performance.
Full program to show that how synchronization block can cost us performance,
we will create two threads on same object, then start both threads, either of the thread will acquire object lock and other thread will wait to acquire lock until lock is released by thread which acquired it>
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class MyClass implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" is waiting for lock");
synchronized (this) {
try {
System.out.println(Thread.currentThread().getName()+" has acquired lock");
Thread.sleep(2000); //sleep for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" has ended");
}
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
Thread thread2=new Thread(obj,"Thread-2");
thread1.start();
thread2.start();
}
}
/*OUTPUT
Thread-1 is waiting for lock
Thread-2 is waiting for lock
Thread-1 has acquired lock
Thread-1 has ended
Thread-2 has acquired lock
Thread-2 has ended
*/
|
What happened in above program ?
Thread1 acquired object lock by entering in synchronized block & Thread2 was waiting for Thread1 to release lock and enter in synchronization block, it costed us performance.
Here i have shown example code that how synchronized block can cost us performance, likewise you may call any synchronized method from run() method, to see how synchronized method can cost us performance.
RELATED LINKS>
Volatile keyword vs synchronized>
Volatile keyword in java- difference between synchronized and volatile, 10 key points about volatile keyword, why volatile variables are not cached in memory
Differences between important thread methods >
Difference between wait() and sleep() method in threads
Differences and similarities between yield() and sleep() in threads
Difference between notify() and notifyAll() methods, with program
Difference between wait() and wait(long timeout) -What will be Thread states
Thread Pool, Thread local, Busy Spin >
Implement Thread pool in java
ThreadLocal in multithreading in java - methods and usage with program
Busy Spin - What is busy spin? Consumer Producer problem with busy spin and solution to busy spin.
Guidelines to threadsafe code >
Guidelines to thread safe code, most important point we must take care of in multithreading programs
Interviews >