Table of Contents
- Why do you need Synchronization?
- Object level locking:
- Class level locking:
- Make static method synchronized:
- Using synchronized block and lock on .class:
- Using synchronized block and lock on some other static object:
- Can two threads execute static and non static methods concurrently?
- If one method of class is synchronized and other method of same class is not synchronized? Can they be executed concurrently by two threads?
- Is it safe to call a synchronized method from another synchronized method?
Why do you need Synchronization?
Let’s understand this with the help of example.
Let’s say you want to count number of request you got for a particular URL. If you get two requests at the same time, then count may be inconsistent.
Without Synchronization:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.arpit.java2blog; public class RequestCounter { private int count; public int incrementCount() { count++; return count; } } |
For example:
Thread T1 sees count as 20 and increment it to 21. At the same time, thread t2 also sees count as 20 and increment it to 21. This shows that count became inconsistent.
With Synchronization:
You can achieve Synchronization using two ways.
- synchronized method
- synchronized block
You can not use synchronized with  instance or class variables.
synchronized method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.arpit.java2blog; public class RequestCounter { private int count; public synchronized int incrementCount() { count++; return count; } } |
Thread T1 sees count as 20 and increment it to 21. At the same time, thread t2 will now see count as 21 and increment it to 22.
synchronized block
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package org.arpit.java2blog; public class RequestCounter { private int count; public int incrementCount() { synchronized (this) { count++; return count; } } } |
Thread T1 sees count as 20 and increment it to 21. At the same time, thread t2 will now see count as 21 and increment it to 22.
There are two types of locking in java.
- Object level locking
- Class level locking
Object level locking:
Make method synchronized:
1 2 3 4 5 |
public synchronized int incrementCount() { } |
Using synchronized block and lock on this:
1 2 3 4 5 6 7 |
public int incrementCount() { synchronized (this) { count++; return count; } |
Using synchronized block and lock on some other object:
1 2 3 4 5 6 7 8 |
private final Object lock=new Object(); public int incrementCount() { synchronized (lock) { count++; return count; } |
Class level locking:
This can be achieved by following:
Make static method synchronized:
1 2 3 4 5 |
public static synchronized int incrementCount() { } |
Using synchronized block and lock on .class:
1 2 3 4 5 6 7 |
public int incrementCount() { synchronized (RequestCounter.class) { count++; return count; } |
Using synchronized block and lock on some other static object:
1 2 3 4 5 6 7 8 |
private final static Object lock=new Object(); public int incrementCount() { synchronized (lock) { count++; return count; } |
Can two threads execute static and non static methods concurrently?
Yes, Since two threads will acquire lock on different objects, they can be executed concurrently without any issues.
If one method of class is synchronized and other method of same class is not synchronized? Can they be executed concurrently by two threads?
Yes, because one thread will require lock to get into synchronized block but second thread which will execute non synchronized method that won’t require any lock, so it can be executed concurrently.
Is it safe to call a synchronized method from another synchronized method?
Yes, it is safe to call a synchronized method from another synchronized method because when you call synchronized method, you will get lock on this object and when you call another synchronized method of same class, it is safe to execute as it already has lock on this object.
For example:
1 2 3 4 5 6 7 8 9 10 |
public synchronized void method1() { method2(); // some code } public synchronized void method2() { // some code } |
You are actually doing this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public void method1() { synchronized (this) { method2(); // some code } } public void method2() { synchronized (this) { // some code } } |
Here if any thread calls method2 from method1, it will already have lock on this object hence It is safe to execute.