Java — java.util.concurrent.locks.ReentrantLock | Code Factory

Code Factory
4 min readJun 4, 2020

Index Page : Link

Donate : Link

WordPress Blog : Link

  • It is the implementation class of Lock interface and it is the direct child class of Object.
  • Reentrant means a thread can aquire same lock multiple times without any issue.
  • Internally reentrant lock increments threads personal count whenever we call lock() method and decrement count value whenever thread calls unlock() method and lock will be released whenever count reached 0.

Constructors :

1. ReentrantLock rl = new ReentrantLock()

  • Creates an instance of ReentrantLock.

2. ReentrantLock rl = new ReentrantLock(boolean fairness)

  • Creates an instance of ReentrantLock with the given fairness policy.
  • If the fairness is true then longest waiting thread can aquire the lock if it is available that is it follows FCFS (First Come First Serve) policy.
  • If the fairness is false then which waiting thread will get the chance we can’t expect.
  • Default vale for fairness is false.

Which of the following declarations are equal :

  1. ReentrantLock rl = new ReentrantLock();
  2. ReentrantLock rl = new ReentrantLock(true);
  3. ReentrantLock rl = new ReentrantLock(false);
  4. All of the above

Important Methods of ReentrantLock :

1. public void lock()

  • Acquires the lock.

2. public boolean tryLock()

  • Acquires the lock only if it is not held by another thread at the time of invocation.

3. public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException

  • Acquires the lock if it is not held by another thread within the given waiting time and the current thread has not been interrupted.

4. public void lockInterruptibly() throws InterruptedException

  • Acquires the lock unless the current thread is interrupted.
  • Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

5. public void unlock()

  • Attempts to release this lock.

6. public int getHoldCount()

  • Queries the number of holds on this lock by the current thread.

7. public boolean isHeldByCurrentThread()

  • Returns true iff lock is hold by current thread.

8. public final int getQueueLength()

  • Returns number of threads waiting for the lock.

9. protected Collection<Thread> getQueuedThreads()

  • Returns a collection of threads which are waiting to get the lock.

10. public final boolean hasQueuedThreads()

  • Returns true if any thread waiting to get the lock.

11. public boolean isLocked()

  • Returns true if lock is aquired by some thread.

12. public final boolean isFair()

  • Returns true if fairness policy is set with the true value.

13. protected Thread getOwner()

  • Returns the thread which aquires the lock.

Example 1 :

package com.example.thread;import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockTest {
public static void main(String... args) {
ReentrantLock rl = new ReentrantLock();
rl.lock();
rl.lock();
System.out.println(rl.isLocked()); // true
System.out.println(rl.isHeldByCurrentThread()); // true
System.out.println(rl.getQueueLength()); // 0
rl.unlock();
System.out.println(rl.getHoldCount()); // 1
System.out.println(rl.isLocked()); // true
rl.unlock();
System.out.println(rl.isLocked()); // false
System.out.println(rl.isFair()); // false
}
}

Example 2 :

package com.example.thread;import java.util.concurrent.locks.ReentrantLock;/**
* @author code.factory
*
*/
public class ReentrantLockTest {
public static void main(String... args) {
Display d = new Display();
MyThread t1 = new MyThread(d, "Narendra");
MyThread t2 = new MyThread(d, "Yogi");
t1.start();
t2.start();
}
}
class Display {
ReentrantLock rl = new ReentrantLock();
public void wish(String name) {
rl.lock(); // #1
for(int i=0; i<5; i++) {
System.out.print("Good Morning ");
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(name);
}
rl.unlock(); // #2
}
}
class MyThread extends Thread {
Display d;
String name;

public MyThread(Display d, String name) {
this.d = d;
this.name = name;
}

public void run() {
d.wish(name);
}
}

Output :

Good Morning Narendra
Good Morning Narendra
Good Morning Narendra
Good Morning Narendra
Good Morning Narendra
Good Morning Yogi
Good Morning Yogi
Good Morning Yogi
Good Morning Yogi
Good Morning Yogi
  • If we comment lines #1 and #2 then the thread will be executed simultaneously and we will get irregular output. If we are not commenting lines #1 and #2 then the thread will be executed one by one and we will get regular output.

Example 3 :

package com.example.thread;import java.util.concurrent.locks.ReentrantLock;/**
* @author code.factory
*
*/
public class ReentrantLockTest {
public static void main(String... args) {
MyThread t1 = new MyThread("First Thread");
MyThread t2 = new MyThread("Second Thread");
t1.start();
t2.start();
}
}
class MyThread extends Thread {
static ReentrantLock rl = new ReentrantLock();
public MyThread(String name) {
super(name);
}

public void run() {
if(rl.tryLock()) {
System.out.println(Thread.currentThread().getName() + " get lock");
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
rl.unlock();
} else {
System.out.println(Thread.currentThread().getName() + " unable to get lock");
}
}
}

Output :

First Thread get lock
Second Thread unable to get lock

Example 4 :

package com.example.thread;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author code.factory
*
*/
public class ReentrantLockTest {
public static void main(String... args) {
MyThread t1 = new MyThread("First Thread");
MyThread t2 = new MyThread("Second Thread");
t1.start();
t2.start();
}
}
class MyThread extends Thread {
static ReentrantLock rl = new ReentrantLock();
public MyThread(String name) {
super(name);
}

public void run() {
do {
try {
if(rl.tryLock(2000, TimeUnit.MILLISECONDS)) {
System.out.println(Thread.currentThread().getName() + " get lock");
Thread.sleep(5000);
rl.unlock();
System.out.println(Thread.currentThread().getName() + " release lock");
} else {
System.out.println(Thread.currentThread().getName() + " unable to get lock");
}
} catch(Exception e) {
e.printStackTrace();
}
} while(true);
}
}

Output :

Second Thread get lock
First Thread unable to get lock
First Thread unable to get lock
First Thread get lock
Second Thread release lock
Second Thread unable to get lock
Second Thread unable to get lock
First Thread release lock
Second Thread get lock
First Thread unable to get lock
First Thread unable to get lock
First Thread get lock
Second Thread release lock
Second Thread unable to get lock
Second Thread unable to get lock
.
.
.

--

--