Java - Synchronized block and method in detail
Java is a multi-threaded programming language. So in every program multiple threads run in parallel to complete the program execution.At this point of time the results may differ or order of execution will change. To prevent the inaccuracy or inconsistency of data results, Java has provided 'synchronized' keyword to implement in 'synchronized block' and 'synchronized method'. The synchronized object won't allow two threads to access at the same time. So that one thread can't be reading while another updates it.The Second Thread should wait until the first is done.
We can achieve synchronization using the '
If you don't want to synchronize some of the variables of particular object or resource, you can declare it as 'volatile'.Remember, synchronized keyword we can't use for variables, only for blocks and methods.
Example program on Synchronized Block:
In the below example when ever we create a new tread, the run method will be called by start() method. In my synchronized block we are locking ThreadSyncExample.class so the lock will be on class level so other thread cannot get access to the class object of ThreadSyncBlock until the first one releases it.Here t1 thread have access first to run.Once t1 comes out of the loop then next thread t2 will be allowed in the block.
Note: if the object used to lock synchronized block of code, ThreadSyncExample.class in the below example is null, then synchronized block will throw a
Use
we can define synchronized methods as two types
Output:
If we want to allow only one thread to access to the run method, we can achieve it by creating another static synchronized method anc call it inside the run method.
Some important points to remember:
We can achieve synchronization using the '
synchronized
' keyword.If you use 'synchronized
' keyword in your program, JVM treats that synchronized java code will only be executed by one thread at a time.We can say it as locking.i.e mutual exclusive access of shared object or resource.If you don't want to synchronize some of the variables of particular object or resource, you can declare it as 'volatile'.Remember, synchronized keyword we can't use for variables, only for blocks and methods.
Example program on Synchronized Block:
In the below example when ever we create a new tread, the run method will be called by start() method. In my synchronized block we are locking ThreadSyncExample.class so the lock will be on class level so other thread cannot get access to the class object of ThreadSyncBlock until the first one releases it.Here t1 thread have access first to run.Once t1 comes out of the loop then next thread t2 will be allowed in the block.
Note: if the object used to lock synchronized block of code, ThreadSyncExample.class in the below example is null, then synchronized block will throw a
NullPointerException
.You should write null check there.package com.javabynataraj; //http://javabynataraj.blogspot.com public class ThreadSyncBlock { public static void main(String[] args) { Thread t1 = new SimpleThread("First Thread"); t1.start(); Thread t2 = new SimpleThread("Second Thread"); t2.start(); } } class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { synchronized (ThreadSyncBlock.class) { for (int i = 0; i < 10; i++) { System.out.println(getName() + " says " + i); try { sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { } } System.out.println(getName() + " is done."); } } }Output:
First Thread says 0 First Thread says 1 First Thread says 2 First Thread says 3 First Thread says 4 First Thread is done. Second Thread says 0 Second Thread says 1 Second Thread says 2 Second Thread says 3 Second Thread says 4 Second Thread is done.Example program on Synchronized method:
Use
synchronized
keyword to for the method declaration, so that JVM can understand that our method is synchronized.we can define synchronized methods as two types
- Synchronized Instance Methods
- Synchronized Static Methods
package com.javabynataraj; //http://javabynataraj.blogspot.com public class ThreadSyncMethod { public static void main(String[] args) throws InterruptedException { Thread t1 = new SimpleThread1("First Thread"); Thread t2 = new SimpleThread1("Second Thread"); t1.start(); t2.start(); } } class SimpleThread1 extends Thread { public SimpleThread1(String str) { super(str); } public synchronized void run() { for (int i = 0; i < 5; i++) { System.out.println(getName() + " says " + i); try { sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { } } System.out.println(getName() + " is done."); } }
Output:
Second Thread says 0 First Thread says 0 Second Thread says 1 First Thread says 1 First Thread says 2 Second Thread says 2 First Thread says 3 First Thread says 4 Second Thread says 3 Second Thread says 4 Second Thread is done. First Thread is done.Synchronized static method: static synchronized methods will synchronize on the class object of the class the synchronized static method belongs to. Here since only one class object is exists in JVM per class.So only one thread can execute inside a static synchronized method in the same class.
If we want to allow only one thread to access to the run method, we can achieve it by creating another static synchronized method anc call it inside the run method.
package com.javabynataraj; //http://javabynataraj.blogspot.com public class ThreadSyncStaticMethod { public static void main(String[] args) throws InterruptedException { Thread t1 = new SimpleThread2("First Thread"); Thread t2 = new SimpleThread2("Second Thread"); t1.start(); t2.start(); } } class SimpleThread2 extends Thread { public SimpleThread2(String str) { super(str); } public void run() { display(); } public static synchronized void display(){ for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " says " + i); try { sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { } } System.out.println(Thread.currentThread().getName() + " is done."); } }OutPut:
First Thread says 0 First Thread says 1 First Thread says 2 First Thread says 3 First Thread says 4 First Thread is done. Second Thread says 0 Second Thread says 1 Second Thread says 2 Second Thread says 3 Second Thread says 4 Second Thread is done.
Some important points to remember:
- We can use
synchronized
keyword on synchronized block or synchronized method but not on constructors or variables. - The lock will be applied on the thread when ever the thread will enters into the synchronized block or method and released when it comes out of the block or method.
- If the object is null, JVM throws a java.lang.NullPointerException.
- Constructors can not be synchronized.By using the
synchronized
keyword with a constructor java compiler will say it is asyntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed. - Instead of making all the code synchronized using method, we can make paticular code(wanted lines of code) can be synchronized uing synchronized block.This will give you good performance. So synchronized block is better than synchronized method.