
- Groovy Tutorial
- Groovy - Home
- Groovy - Overview
- Groovy - Environment
- Groovy - Basic Syntax
- Groovy - Data Types
- Groovy - Variables
- Groovy - Optionals
- Groovy - Numbers
- Groovy - Strings
- Groovy - Ranges
- Groovy - Lists
- Groovy - Maps
- Groovy - Dates & Times
Groovy Operators
- Groovy - Operators
- Groovy - Arithmetic Operators
- Groovy - Assignment Operators
- Groovy - Relational Operators
- Groovy - Logical Operators
- Groovy - Bitwise Operators
- Groovy - Spaceship Operator
- Groovy - in Operator
- Groovy - Elvis Operator
- Groovy - Safe Navigation Operator
- Groovy Operator Precedence & Associativity
Control Statements
- Groovy - Decision Making
- Groovy - If Else Statement
- Groovy - Switch Statement
- Groovy - Loops
- Groovy - For Loop
- Groovy - For-in Loop
- Groovy - While Loop
- Groovy - Do While Loop
- Groovy - Break Statement
- Groovy - Continue Statement
Groovy File Handling
- Groovy - File I/O
- Java - Create a File
- Java - Write to File
- Java - Append to File
- Java - Read Files
- Java - Delete Files
- Java - File Properties
- Java - File Existence and Type
- Java - File Size
- Java - File Permissions
- Java - Directories
- Java - Listing Directories
- Java - Filtering Files/Directories
- Java - Deleting Directories
- Java - Renaming Files/Directories
Groovy Error & Exceptions
- Groovy - Exception Handling
- Groovy - try-catch Block
- Groovy - try-with-resources
- Groovy - Multi-catch Block
- Groovy - Nested try Block
- Groovy - Finally Block
- Groovy - throw Exception
- Groovy - Exception Propagation
- Groovy - Built-in Exceptions
- Groovy - Custom Exception
Groovy Multithreading
- groovy - Multithreading
- groovy - Thread Life Cycle
- groovy - Creating a Thread
- groovy - Starting a Thread
- groovy - Joining Threads
- groovy - Naming Thread
- groovy - Thread Scheduler
- groovy - Thread Pools
- groovy - Main Thread
- groovy - Thread Priority
- groovy - Daemon Threads
- groovy - Shutdown Hook
Groovy Synchronization
- groovy - Synchronization
- groovy - Block Synchronization
- groovy - Static Synchronization
- groovy - Inter-thread Communication
- groovy - Thread Deadlock
- groovy - Interrupting a Thread
- groovy - Thread Control
- groovy - Reentrant Monitor
- Groovy - Methods
- Groovy - Methods
- Groovy - Optional parenthesis
- Groovy - Named Arguments
- Groovy - Closures as Arguments
- Groovy - Method Overloading
- Groovy - Method Scope and Visibility
- Groovy - isCase Method
- Groovy - Implicit Return
- Groovy - Variable Arguments
- Groovy - Regular Expressions
- Groovy - Regular Expressions
- Groovy - Defining Regular Expressions
- Groovy - Matcher Object
- Groovy - Regex Tasks
- Groovy - XML
- Groovy - XML
- Groovy - Parsing XML
- Groovy - Creating XML
- Groovy - Modifying XML
- Groovy - Querying XML
- Groovy - Simplified Notation
- Groovy - Closure based Querying
- Groovy - Closure based Creation
- Groovy - JSON
- Groovy - JSON
- Groovy - Parsing JSON
- Groovy - Creating JSON using JsonOutput
- Groovy - Creating JSON using JsonBuilder
- Groovy - Modifying JSON
- Groovy - Error Handling
- Groovy - Handling JSON Arrays
- Groovy - JSON Array Operations
- Groovy - JSON Objects
- Groovy - JSON Object Operations
- Groovy - Generics
- Groovy - Generics
- Groovy - Declaring Generic Types
- Groovy - Bound Type Parameters
- Groovy - Wild Cards
- Groovy - Miscellaneous
- Groovy - Object Oriented
- Groovy - Closures
- Groovy - Annotations
- Groovy - JMX
- Groovy - DSLS
- Groovy - Database
- Groovy - Builders
- Groovy - Command Line
- Groovy - Unit Testing
- Groovy - Template Engines
- Groovy - Meta Object Programming
- Groovy Useful Resources
- Groovy - Quick Guide
- Groovy - Useful Resources
- Groovy - Discussion
Groovy - Reentrant Monitor
ReetrantLock is a class that implements Lock Interface. It provides the synchronization feature with great flexibility which is why it is the most used lock class in Groovy. It is necessary for the reliable and fair working of thread. Here, threads are small sub-processes of a big operation. In this article, we are going to learn ReetrantLock and how they manage threads so that they can work efficiently.
Working of ReetrantLock
When multiple threads try to access a shared resource then, ReetrantLock restricts access to a single thread at a time through lock() and unlock() methods. Suppose there are three people trying to book a train ticket. At the same time, all three people will try to access the booking system, it may happen that two people end up booking the same seat. Reetrant Lock can handle this situation.
First, all three people will request to acquire the booking system through tryLock() method. When one acquires the booking system then, it restricts the particular seat booking through lock() method. After booking, the person will call the unlock() method to release the acquired lock. Till the resources are busy other people will wait in a queue for their turn and after the release of lock they will come in a runnable state.
ReetrantLock tries to provide locks in a fair manner. We can set for how long a thread can acquire lock and also, it ensures that a thread with the longest wait time may get access to lock first. By default the locks are unfair, to make it fair we need to pass Boolean value true in its constructor.
Syntax
ReentrantLock nameOflock = new ReentrantLock(); // by default false Or, ReentrantLock nameOflock = new ReentrantLock(true); // we can make it true
The locks are explicit and can lock or unlock in any order. A single thread can ask for the lock multiple times that's the reason the name of lock is Reentrant. We can count the number of times a lock is acquired by using getHoldCount() method.
Example - Multithreading Without Reentrant Lock
The following example illustrates the multithreading witout use of Reetrant Lock in above code. We've created a class Thrd with a method operation() to perform a given task. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example.groovy
class Example { static void main(String[] args) { // creating object for thread class Thread1 oprt1 = new Thread1(); Thread2 oprt2 = new Thread2(); Thread3 oprt3 = new Thread3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } } class Utility { static void operation(int data) { for(int i = 1; i <= 4; i++) { println(data++); } } } class Thread1 extends Thread { // thread number 1 public void run() { Utility.operation(1); } } class Thread2 extends Thread { // thread number 2 public void run() { Utility.operation(5); } } class Thread3 extends Thread { // thread number 3 public void run() { Utility.operation(10); } }
This produces a different result every time you run this program −
Output
This will produce the following result−
1 2 3 4 10 11 12 13 5 6 7 8
Example - Multithreading With Reentrant Lock
The following example illustrates the use of Reetrant Lock in above code. We've created a class Thrd and inside this thread, we've defined an object of ReentrantLock. A method operation() store the Boolean value of tryLock() method to a variable named lockAcquired which will check if lock gets acquired by any thread or not. If the lock is acquired lock is given to that thread using lock() method and then the thread start performing the given task. The task will be performed in the try block and the lock will be released in the finally block using unlock() method. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example.groovy
import java.util.concurrent.locks.ReentrantLock; class Example { static void main(String[] args) { // creating object for thread class Thread1 oprt1 = new Thread1(); Thread2 oprt2 = new Thread2(); Thread3 oprt3 = new Thread3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } } class Utility { // creating object of ReentrantLock class private static ReentrantLock lockr = new ReentrantLock(); static void operation(int data) { // give access to lock boolean lockAcquired = lockr.tryLock(); if (lockAcquired) { try { lockr.lock(); // giving lock to thread for(int i = 1; i <= 4; i++) { println(data++); } // checking lock count println("Count of Lock: " + lockr.getHoldCount()); } finally { lockr.unlock(); // unlocking the lock } } else { println("I am in else block"); } } } class Thread1 extends Thread { // thread number 1 public void run() { Utility.operation(1); } } class Thread2 extends Thread { // thread number 2 public void run() { Utility.operation(5); } } class Thread3 extends Thread { // thread number 3 public void run() { Utility.operation(10); } }
This produces a different result every time you run this program −
Output
I am in else block 1 2 3 4 I am in else block Count of Lock: 2
Example - Multithreading With Reentrant Lock as True
The following example illustrates the use of Reetrant Lock in above code. We've created a class Thrd and inside this thread, we've defined an object of ReentrantLock with fair value as true. A method operation() store the Boolean value of tryLock() method to a variable named lockAcquired which will check if lock gets acquired by any thread or not. If the lock is acquired lock is given to that thread using lock() method and then the thread start performing the given task. The task will be performed in the try block and the lock will be released in the finally block using unlock() method. Now we've created three thread classes and call the operation() method. In the main() method, three objects of thread class are defined and their start() method to start the execution of threads.
Example.groovy
import java.util.concurrent.locks.ReentrantLock; class Example { static void main(String[] args) { // creating object for thread class Thread1 oprt1 = new Thread1(); Thread2 oprt2 = new Thread2(); Thread3 oprt3 = new Thread3(); // Starting the thread operation oprt1.start(); oprt2.start(); oprt3.start(); } } class Utility { // creating object of ReentrantLock class private static ReentrantLock lockr = new ReentrantLock(true); static void operation(int data) { // give access to lock boolean lockAcquired = lockr.tryLock(); if (lockAcquired) { try { lockr.lock(); // giving lock to thread for(int i = 1; i <= 4; i++) { println(data++); } // checking lock count println("Count of Lock: " + lockr.getHoldCount()); } finally { lockr.unlock(); // unlocking the lock } } else { println("I am in else block"); } } } class Thread1 extends Thread { // thread number 1 void run() { Utility.operation(1); } } class Thread2 extends Thread { // thread number 2 void run() { Utility.operation(5); } } class Thread3 extends Thread { // thread number 3 void run() { Utility.operation(10); } }
This produces a different result every time you run this program −
Output
I am in else block 1 I am in else block 2 3 4 Count of Lock: 2