Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Synchronisation
2.1.
Types of Synchronisation
2.2.
Why Synchronisation?
3.
Reentrant Monitor in Java
3.1.
Background - Need for Reentrant Monitors
3.2.
Java Monitors are Reentrant
4.
Difference between ReentrantLock and Synchronized Keywords
5.
Reentrant Locks
5.1.
Basic Implementation
5.1.1.
Output
6.
Reentrant Lock Methods
7.
Advantages of ReentrantLock in Java
8.
Limitations of ReentrantLock in Java
9.
FAQs
10.
Key Takeaways
Last Updated: Mar 27, 2024

Reentrant Monitor in Java

Crack Google SDE interview : Essential projects
Speaker
Saurav Prateek
SDE-2 @
20 Jun, 2024 @ 01:30 PM

Introduction

Can you differentiate between thread and process? A process is an active programme that is currently running. A thread is a small, self-contained process that a scheduler can handle independently. 

Do you know our PCs can handle multiple threads accessing the same resources simultaneously? This article will discuss the ReentrantLock class that implements the Lock interface and ensures that methods of accessing shared resources are correctly synchronised.

After reading this article, I hope you will better understand Reentrant monitors in Java. Let’s get started by learning a few fundamental concepts in the beginning.

Also Read About, Multithreading in java, Multithreading in Python

Synchronisation

In Java, synchronisation refers to the ability to regulate multiple threads' access to a shared resource. When multiple threads try to access shared resources simultaneously, it can have unpredictable effects. Synchronisation is required for thread communication to be reliable and well manageable.

Types of Synchronisation


There are two types of Synchronisation:

  1. Process Synchronisation: 
    In process Synchronisation, the resources like memory, CPU execution time, etc., are allocated to the processes by the operating system.
  2. Thread Synchronisation:
    Threads are nothing but just simple processes or sub-processes. When two or more threads try to access the same resource simultaneously in Java, the java runtime slows or suspends the execution of one or more threads. Thread synchronisation is a technique for resolving this issue.

Why Synchronisation?

  • We can avoid Thread interference with the use of synchronisation.
  • Synchronisation aids in the prevention of concurrency issues.
Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Reentrant Monitor in Java

In the above section, we discussed a brief overview of the synchronisation concept that will help you grasp the significance of the Reentrant monitor in Java.

Read More About, Basics of Java

Background - Need for Reentrant Monitors

The synchronised keyword is the standard technique to accomplish thread synchronisation in Java. Although it provides basic synchronisation methods, it suffers from various drawbacks.

  • The synchronised keyword is only applicable to methods and blocks; it can’t handle classes and variables.
  • Synchronised blocks don't have a waiting queue; thus, any other thread can take the lock if one thread exits. This could lead to a scarcity of resources.

To overcome these problems, we use the Reentrant monitor in Java. In Java, reentrant locks are used to allow more flexibility in synchronisation. It has various advantages over the traditional synchronised keyword. Let’s understand it in more detail in the next section.

Java Monitors are Reentrant

Suppose you wish to access both synchronised methods in a program on a single thread, and you're using more than one synchronised method in the program. However, on a single thread, a single lock can only be acquired for one synchronised method at a time. As a result, we're employing Reentrant Monitor to solve this issue. 

Java monitors are reentrant implies a Java thread can reuse the same monitor for different synchronised methods if the method is called from the method.

Let’s understand it clearly from the following example of a java class:

class ReentrantClass {
    public synchronized void function1() {
        function2();
        System.out.println("here I am, in function1()");
    }
    public synchronized void function2() {
        System.out.println("here I am, in function2()");
    }
}  

Explanation: 

Here, the ReentrantClass has two methods: function1 and function2. The synchronised ‘function1’ calls ‘function2.’ 

The current thread can reclaim the Reentrant object's monitor, and both ‘function1’ and ‘function2’ execute to completion. The current thread acquires the monitor when the control enters method ‘function1’. Now ‘function1’ calls ‘function2’, and because ‘function2’ is synchronised, the thread tries to acquire the same monitor once more. This works because Java allows reentrant monitors.

Basic Advantages: 

  • Reentrant Monitor is a feature that allows a Java thread to reuse the same monitor for many synchronised methods if they are called from the same method.
  • It avoids the danger of single thread deadlocking.

    You can also read about the Multiple Inheritance in Java.

Difference between ReentrantLock and Synchronized Keywords

The basic differences are given below:

Reentrant Locks

Let’s start by defining what a Lock is. Locks are commonly used to prevent other threads from changing states simultaneously. 

The ReentrantLock class implements the Lock interface and ensures that methods accessing shared resources are synchronised. Calls to the lock and unlock methods surround the code that manipulates the shared resource. This gives the current working thread a lock on the shared resource and prevents other threads from doing so.

ReentrantLock, as the name implies, allows threads to enter the lock on a resource many times. A “hold count” of one is set when the thread initially enters the lock. Before unlocking, the thread can re-enter lock mode, and the hold count is increased by one each time. The “hold count” is decremented by one for each “unlock” request, and when the “hold count” reaches 0, the resource is unlocked.

Basic Implementation

Let’s look at what a basic reentrant lock implementation looks like. Even if an exception is raised in the method body, the unlock statement is always called in the finally block to ensure that the lock is freed (try block).

Steps to be followed:

  1. Create a ReentrantLock object first.
  2. To execute, create a Runnable Object and pass the lock to it.
  3. To gain access to a shared resource, use the lock() method.
  4. Execute unlock() when you've finished your task to unlock the lock.
//reentrant lock implementation
import java.util.concurrent.locks.ReentrantLock;
public class reentrantlock {
    public static void main(String[] args) {
        //create a lock
        ReentrantLock lock = new ReentrantLock();
        //create a thread
        lock.lock();
        try {
            System.out.println("Lock acquired");
        }
        //catch exception
        catch (Exception e) {
            System.out.println("Exception caught");
        }
        //release the lock
        finally {
            lock.unlock();
            System.out.println("Lock released");
        }
    }
}

Output

Practice it on online java compiler for better understanding.

Reentrant Lock Methods

The important reentrant lock methods are given below:

Advantages of ReentrantLock in Java

The following is a list of the advantages of ReentrantLock over synchronised in Java:

  1. Interruptible locking capability.
  2. The ability to set a timer while waiting for the lock to be activated.
  3. The ability to construct a fair lock.
  4. API to retrieve a list of threads waiting for a lock.
  5. The ability to attempt a lock without being blocked.

Limitations of ReentrantLock in Java

  • The disadvantage of adopting ReentrantLock is that it wraps method bodies within try-finally blocks, making code unreadable and hiding business logic because ‘finally’ is necessary to invoke the unlock function.
  • When it comes to locks, the programmer is in charge of acquiring and releasing them. If the programmer forgets to release the lock in the “finally” block, it can lead to subtle errors.

 

Must Read Static Blocks In Java.

FAQs

  1. Is it possible for the same thread to hold the lock twice?
    Without running into deadlocks, a thread can safely acquire the same lock many times (e.g. a synchronised method calls another synchronised method on the same object).
     
  2. What is the difference between a Process and a Thread?
    A process is an active program that is currently running. A thread is a small, self-contained process that a scheduler can handle independently. Context switching takes longer with processes because they are more time-consuming. Because threads are lighter than processes, they take less time to transfer contexts.
     
  3. In Java, which method can be used to determine whether a thread is locked?
    holdLock() is a method in Java Thread that locks the thread. If the current thread holds the monitor lock on the supplied object, the holdLock() method of the Thread class returns true.
     
  4. Is it possible for a synchronised method to be static?
    In Java, a static synchronised method is a way of synchronising a method so that no two threads can act on the synchronised method simultaneously. The only change is that Static Synchronized is used instead of Dynamic Synchronized. We're achieving a class-level lock, which means that only one thread can use the method.
     
  5. What does multithreading mean?
    Multithreading is a programme execution mechanism that allows several threads to be formed within a process, each of which can execute independently while sharing process resources.

Key Takeaways

In this article, we have discussed the Reentrant monitor in Java. Initially, we clarified a few basic concepts on the synchronisation in java; then, we learnt various reentrant monitor methods and the basic implementation of reentrant lock. In the end, we discussed the advantages and disadvantages of the reentrant monitor.

We hope this blog has helped you enhance your knowledge regarding Reentrant Monitor in Java. If you want to learn more, check out our articles on ‘Synchronization in Java’ and ‘Introduction to process synchronisation.’ Do upvote our blog to help other ninjas grow.

Head over to our practice platform Coding Ninjas Studio to practice top problems, attempt mock tests, read interview experiences, and much more.!

Happy Reading!

Previous article
Interrupting thread
Next article
Lock frameworks vs. thread synchronization
Live masterclass