Object level locking vs Class level locking in java

Synchronization is ability to restrict access to shared resource to only one thread. When two or more threads need access to shared resource, there has to be some mechanism such that shared resource will be used by only one thread. The process by which we can achieve it is called Synchronization.

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

packageorg.arpit.java2blog;

publicclassRequestCounter{

privateintcount;

publicintincrementCount()

{

count++;

returncount;

}

}

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

You can make whole incrementCount() method synchronized so no two thread can access it parallelly.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packageorg.arpit.java2blog;

publicclassRequestCounter{

privateintcount;

publicsynchronized intincrementCount()

{

count++;

returncount;

}

}

For example:
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

You can make use block to synchronize critical section in incrementCount() method so no two thread can access block concurrently.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

packageorg.arpit.java2blog;

publicclassRequestCounter{

privateintcount;

publicintincrementCount(){

synchronized(this){

count++;

returncount;

}

}

}

For example:
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:

Object level locking means you want to synchronize non static method or block so that it can be accessed by only one thread at a time for that instance. It is used if you want to protect non static data.

You can achieve Object level locking by following.

Make method synchronized:

1

2

3

4

5

publicsynchronized intincrementCount()

{

}

Using synchronized block and lock on this:

1

2

3

4

5

6

7

publicintincrementCount(){

synchronized(this){

count++;

returncount;

}

Using synchronized block and lock on some other object:

1

2

3

4

5

6

7

8

privatefinalObjectlock=newObject();

publicintincrementCount(){

synchronized(lock){

count++;

returncount;

}

Class level locking:

Class level locking means you want to synchronize static method or block so that it can be accessed by only one thread for whole class. If you have 10 instances of class, only one thread will be able to access only one method or block of any one instance at a time. It is used if you want to protect static data.

This can be achieved by following:

Make static method synchronized:

1

2

3

4

5

publicstaticsynchronized intincrementCount()

{

}

Using synchronized block and lock on .class:

1

2

3

4

5

6

7

publicintincrementCount(){

synchronized(RequestCounter.class){

count++;

returncount;

}

Using synchronized block and lock on some other static object:

1

2

3

4

5

6

7

8

privatefinalstaticObjectlock=newObject();

publicintincrementCount(){

synchronized(lock){

count++;

returncount;

}

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

publicsynchronized voidmethod1(){

method2();

// some code

}

publicsynchronized voidmethod2(){

// some code

}

You are actually doing this.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

publicvoidmethod1(){

synchronized(this){

method2();

// some code

}

}

publicvoidmethod2(){

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.