S12L21 – Reentrant lock in multithreading

Java Multithreading with Reentrant Lock

Table of Contents

  1. Introduction
  2. Understanding Reentrant Lock
  3. Code Example with Explanation
  4. Advantages of Reentrant Lock
  5. Conclusion

1. Introduction

In Java multithreading, ensuring thread safety is essential to avoid race conditions when multiple threads access shared resources. Java provides several mechanisms to achieve this, with the synchronized keyword being the most common. However, for more flexibility, the ReentrantLock class from the java.util.concurrent.locks package is used. In this article, we will explore the Reentrant Lock in detail and understand how it works in Java’s multithreading context.

2. Understanding Reentrant Lock

A Reentrant Lock is a type of lock that allows the same thread to enter a locked code block more than once, without causing a deadlock. Unlike synchronized, ReentrantLock provides more control over the locking process with features like:

  • Lock fairness (ensuring that threads are granted access based on the order of their requests).
  • Ability to interrupt a thread waiting for a lock.
  • Option to attempt to acquire the lock without blocking.

Key Features of Reentrant Lock:

Feature Description
Lock Fairness Ensures threads access the lock in order of request.
Interruptible Locks Allows a thread to be interrupted while waiting for a lock.
Timeout on Lock Option to wait for a specified time before giving up on acquiring the lock.

3. Code Example with Explanation

Below is an example of how to use a Reentrant Lock in Java for thread synchronization. The program demonstrates two threads incrementing a shared counter using a Reentrant Lock to prevent concurrent access issues.

Code Explanation:

  • Shared Resource: The counter variable is shared between two threads. Without synchronization, both threads could access and modify this value simultaneously, leading to incorrect results.
  • Reentrant Lock: The ReentrantLock object lock is used to ensure that only one thread accesses the critical section of code (i.e., the increment operation on counter) at a time.
  • Lock Acquisition: Each thread acquires the lock using lock.lock() before entering the critical section and releases it using lock.unlock() after exiting the critical section, ensuring mutual exclusion.
  • Thread Execution: The join() method ensures that the main thread waits for both threads to complete their execution before printing the final counter value.

Output:

4. Advantages of Reentrant Lock

Compared to the synchronized keyword, Reentrant Lock offers several advantages:

Feature synchronized ReentrantLock
Lock Acquisition Implicitly handles lock control Manually acquire and release lock
Lock Fairness Not supported Supported
Timeout Option Not supported Supported
Interruptible Lock Not supported Supported
Flexibility Less flexible More flexible (reentrant behavior)

When to Use Reentrant Lock?

  • When you need more control over the locking mechanism.
  • When you want to use features like fairness, tryLock, or interruptible locks.
  • For advanced thread management scenarios where synchronized isn’t sufficient.

5. Conclusion

The Reentrant Lock in Java provides a powerful way to control thread access to shared resources in a flexible and efficient manner. By offering features like lock fairness, timeout, and interruptibility, it enhances thread synchronization over the traditional synchronized keyword. Understanding when and how to use ReentrantLock is key to managing multithreaded programs efficiently.