Saturday, November 4, 2017

3.5 - Object Level lock and Class Level lock AND Reason Why Wait , Notify and NotifyAll are in Object Class.




Object level lock vs Class level lock in Java


In Java, a synchronized block of code can only be executed by one thread at a time. Also, java supports multiple threads to be executed concurrently. This may cause two or more threads to access the same fields or objects at same time.
Synchronization is the process which keeps all concurrent threads in execution to be in sync. Synchronization avoids memory consistence errors caused due to inconsistent view of shared memory. When a method is declared as synchronized; the thread holds the monitor or lock object for that method’s object. If another thread is executing the synchronized method, your thread is blocked until that thread releases the monitor.
Please note that we can use synchronized keyword in the class on defined methods or blocks. synchronized keyword can not be used with variables or attributes in class definition.

1. Object level lock in Java

Object level lock is mechanism when we want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on given instance of the class. This should always be done to make instance level data thread safe.
Object level locking can be done as below :

Various ways for object level locking
public class DemoClass

{

    public synchronized void demoMethod(){}

}

or

public class DemoClass

{

    public void demoMethod(){

        synchronized (this)

        {

            //other thread safe code

        }

    }

}

or

public class DemoClass

{

    private final Object lock = new Object();

    public void demoMethod(){

        synchronized (lock)

        {

            //other thread safe code

        }

    }

}

2. Class level lock in Java
Class level lock prevents multiple threads to enter in synchronized block in any of all available instances of the class on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads.
Class level locking should always be done to make static data thread safe. As we know that static keyword associate data of methods to class level, so use locking at static fields or methods to make it on class level.

Various ways for class level locking
public class DemoClass

{

    //Method is static

    public synchronized static void demoMethod(){

    }

}

or

public class DemoClass

{

    public void demoMethod()

    {

        //Acquire lock on .class reference

        synchronized (DemoClass.class)

        {

            //other thread safe code

        }

    }

}

or

public class DemoClass

{

    private final static Object lock = new Object();

    public void demoMethod()

    {

        //Lock object is static

        synchronized (lock)

        {

            //other thread safe code

        }

    }

}
3. Object level lock vs class level lock – Important notes
  1. Synchronization in Java guarantees that no two threads can execute a synchronized method, which requires same lock, simultaneously or concurrently.
  2. synchronized keyword can be used only with methods and code blocks. These methods or blocks can be static or non-static both.
  3. When ever a thread enters into Java synchronized method or block it acquires a lock and whenever it leaves synchronized method or block it releases the lock. Lock is released even if thread leaves synchronized method after completion or due to any Error or Exception.
  4. Java synchronized keyword is re-entrant in nature it means if a synchronized method calls another synchronized method which requires same lock then current thread which is holding lock can enter into that method without acquiring lock.
  5. Java synchronization will throw NullPointerException if object used in synchronized block is null. For example, in above code sample if lock is initialized as null, the “synchronized (lock)” will throw NullPointerException.
  6. Synchronized methods in Java put a performance cost on your application. So use synchronization when it is absolutely required. Also, consider using synchronized code blocks for synchronizing only critical section of your code.
  7. It’s possible that both static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on different object.
  8. According to the Java language specification you can not use synchronized keyword with constructor. It is illegal and result in compilation error.
  9. Do not synchronize on non final field on synchronized block in Java. because reference of non final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all.
  10. Do not use String literals because they might be referenced else where in the application and can cause deadlock. String objects created with new keyword can be used safely. But as a best practice, create a new private scoped Object instance OR lock on the shared variable itself which we want to protect. [Thanks to Anu to point this out in comments.






Object level locking vs Class level locking in java


Previous
Next
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:


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.
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.
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:

Using synchronized block and lock on this:

Using synchronized block and lock on some other object:

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:

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?

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:
You are actually doing this.
Here if any thread calls method2 from method1, it will already have lock on this object hence It is safe to execute.




Reason Why Wait , Notify and NotifyAll are in Object Class


1) Wait and notify is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don’t confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.
2 )Locks are made available on per Object basis, which is another reason wait and notify is declared in Object class rather then Thread class.

3) In Java in order to enter critical section of code, Threads needs lock and they wait for lock, they don't know which threads holds lock instead they just know the lock is hold by some thread and they should wait for lock instead of knowing which thread is inside the synchronized block and asking them to release lock. this analogy fits with wait and notify being on object class rather than thread in Java.


No comments:

Post a Comment