ReentrantLock in Java

A Reentrant lock is an implementation of java.util.concurrent.Lock interface with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

Lock is acquired by lock() method and held by Thread until a call to unlock() method. ReentrantLock provides same visibility and ordering guarantee, provided by implicit locking mechanism(synchronized), which means, unlock() happens before another thread gets lock().
You can read also the difference between Lock and synchronized here

Disadvantage of ReentrantLock

Developers are responsible to use lock() method for acquiring the lock and unlock() method for releasing the lock and allow the other threads to run on critical section’s code. If developers forget to call the unlock() method at the end of the critical section, the other threads that are waiting for acquiring the lock will be waiting forever, causing a deadlock situation.

Simple usage of ReentrantLock implementation

class A {
   private final ReentrantLock lock = new ReentrantLock();
   // ...
   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
}

If you want to read about Lock interface please read Lock in Java

A reentrant lock will allow the lock holder to enter blocks of code even after it has already obtained the lock by entering other blocks of code.

Features of ReentrantLock

1) The ability to have more than one condition variable per monitor. This means reentrant locks support more than one wait()/notify() queue.
2) The ability to make the lock “fair”. “fair” locks favor granting access to the longest-waiting thread.
3) The ability to check if the lock is being held.
4) The ability to get the list of threads waiting on the lock.
5) The ability to lock interruptibly.
6) The ability to timeout while waiting for lock.

Example of ReentrantLock

This class represent the custom arraylist to which we can add number of elements. A lock is maintained by custom arraylist for adding new elements to the custom arraylist one after another.

package com.roytuts.concurrent.reentrant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class CustomeArrayList<E> {
    private final Lock lock = new ReentrantLock();
    private List<E> list = new ArrayList<>();
    public void addElement(E e) {
        lock.lock();
        try {
            list.add(e);
            System.out.println("Element (" + e + ") added by " + Thread.currentThread().getName());
        } finally {
            lock.unlock();
        }
    }
}

This class represents an independent adding which could be submitted to custom arralist. This class implements Runnable interface, so that AddingJob can execute it when its turn comes.

package com.roytuts.concurrent.reentrant;
public class AddingJob<E> implements Runnable {
    private E element;
    private CustomeArrayList<E> arrayList;
    public AddingJob(CustomeArrayList<E> arrayList, E element) {
        this.arrayList = arrayList;
        this.element = element;
    }
    @Override
    public void run() {
        arrayList.addElement(element);
    }
}

The main class

package com.roytuts.concurrent.reentrant;
public class ReentrantLockExample {
    public static void main(String[] args) {
        CustomeArrayList<String> arrayList = new CustomeArrayList<>();
        Thread[] thread = new Thread[20];
        for (int i = 0; i < thread.length; i++) {
            thread[i] = new Thread(new AddingJob<String>(arrayList, String.valueOf(i)));
        }
        for (int i = 0; i < thread.length; i++) {
            thread[i].start();
        }
    }
}

Console output

Element (1) added by Thread-1
Element (3) added by Thread-3
Element (5) added by Thread-5
Element (7) added by Thread-7
Element (9) added by Thread-9
Element (11) added by Thread-11
Element (13) added by Thread-13
Element (15) added by Thread-15
Element (17) added by Thread-17
Element (19) added by Thread-19
Element (0) added by Thread-0
Element (2) added by Thread-2
Element (4) added by Thread-4
Element (6) added by Thread-6
Element (8) added by Thread-8
Element (10) added by Thread-10
Element (12) added by Thread-12
Element (14) added by Thread-14
Element (16) added by Thread-16
Element (18) added by Thread-18

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *