Java ReentrantLock Example


In Java, ReentrantLock is a synchronization mechanism provided by the java.util.concurrent.locks package. It is an implementation of the Lock interface that allows multiple threads to access a shared resource with exclusive or shared access. It is an alternative to the traditional synchronization provided by the synchronized keyword.

ReentrantLock offers the following key features:

  1. Locking and Unlocking: Threads can acquire the lock by calling the lock() method and release it using the unlock() method. Only one thread can hold the lock at a time.
  2. Reentrancy: A thread can acquire the lock multiple times, provided it releases the lock an equal number of times. This allows for nested critical sections within the same thread.
  3. Fairness: ReentrantLock can be configured to provide fairness in lock acquisition. When fairness is enabled, the lock favors the longest waiting thread to acquire the lock.
  4. Condition Variables: ReentrantLock supports the use of condition variables, which allow threads to wait for specific conditions to be met before proceeding.

It is important to note that ReentrantLock requires explicit lock acquisition and release, and it is the programmer’s responsibility to ensure proper usage to avoid potential issues such as deadlocks and race conditions.

Here’s an example that demonstrates the usage of ReentrantLock in Java:

ReentrantLockExample.java
package org.websparrow;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private static final ReentrantLock lock = new ReentrantLock();
    private static int counter = 0;

    public static void main(String[] args) {

        Thread thread1 = new Thread(ReentrantLockExample::incrementCounter);
        Thread thread2 = new Thread(ReentrantLockExample::incrementCounter);

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Counter: " + counter);
    }

    private static void incrementCounter() {
        lock.lock(); // Acquire the lock

        try {
            for (int i = 0; i < 1000; i++) {
                counter++; // Critical section: Increment the counter
            }
        } finally {
            lock.unlock(); // Release the lock
        }
    }
}

In this example, we have a shared variable counter that needs to be incremented by multiple threads concurrently. We use a ReentrantLock named lock to ensure that only one thread can access the counter variable at a time.

In the incrementCounter() method, the lock.lock() statement acquires the lock before entering the critical section, where the counter is incremented in a loop. Once the loop is complete, the lock.unlock() statement releases the lock, allowing other threads to acquire it.

By using the ReentrantLock, we ensure that each thread increments the counter safely without any race conditions. After both threads finish their execution, we print the final value of the counter variable.

References

  1. ReentrantLock- JavaDoc
  2. Lock- JavaDoc

Similar Posts

About the Author

Atul Rai
I love sharing my experiments and ideas with everyone by writing articles on the latest technological trends. Read all published posts by Atul Rai.